ActivityManagerService.java revision 66c4a824b9b11a47c7bd1bf858d92fe207409ab9
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;
33import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
34
35import android.Manifest;
36import android.app.AppOpsManager;
37import android.app.ApplicationThreadNative;
38import android.app.IActivityContainer;
39import android.app.IActivityContainerCallback;
40import android.app.IAppTask;
41import android.app.ITaskStackListener;
42import android.app.ProfilerInfo;
43import android.app.admin.DevicePolicyManager;
44import android.app.usage.UsageEvents;
45import android.app.usage.UsageStatsManagerInternal;
46import android.appwidget.AppWidgetManager;
47import android.content.res.Resources;
48import android.graphics.Bitmap;
49import android.graphics.Point;
50import android.graphics.Rect;
51import android.os.BatteryStats;
52import android.os.PersistableBundle;
53import android.os.storage.IMountService;
54import android.os.storage.StorageManager;
55import android.service.voice.IVoiceInteractionSession;
56import android.util.ArrayMap;
57import android.util.ArraySet;
58import android.util.SparseIntArray;
59
60import com.android.internal.R;
61import com.android.internal.annotations.GuardedBy;
62import com.android.internal.app.IAppOpsService;
63import com.android.internal.app.IVoiceInteractor;
64import com.android.internal.app.ProcessMap;
65import com.android.internal.app.ProcessStats;
66import com.android.internal.os.BackgroundThread;
67import com.android.internal.os.BatteryStatsImpl;
68import com.android.internal.os.ProcessCpuTracker;
69import com.android.internal.os.TransferPipe;
70import com.android.internal.os.Zygote;
71import com.android.internal.util.FastPrintWriter;
72import com.android.internal.util.FastXmlSerializer;
73import com.android.internal.util.MemInfoReader;
74import com.android.internal.util.Preconditions;
75import com.android.server.AppOpsService;
76import com.android.server.AttributeCache;
77import com.android.server.IntentResolver;
78import com.android.server.LocalServices;
79import com.android.server.ServiceThread;
80import com.android.server.SystemService;
81import com.android.server.SystemServiceManager;
82import com.android.server.Watchdog;
83import com.android.server.am.ActivityStack.ActivityState;
84import com.android.server.firewall.IntentFirewall;
85import com.android.server.pm.Installer;
86import com.android.server.pm.UserManagerService;
87import com.android.server.statusbar.StatusBarManagerInternal;
88import com.android.server.wm.AppTransition;
89import com.android.server.wm.WindowManagerService;
90import com.google.android.collect.Lists;
91import com.google.android.collect.Maps;
92
93import libcore.io.IoUtils;
94
95import org.xmlpull.v1.XmlPullParser;
96import org.xmlpull.v1.XmlPullParserException;
97import org.xmlpull.v1.XmlSerializer;
98
99import android.app.Activity;
100import android.app.ActivityManager;
101import android.app.ActivityManager.RunningTaskInfo;
102import android.app.ActivityManager.StackInfo;
103import android.app.ActivityManagerInternal;
104import android.app.ActivityManagerNative;
105import android.app.ActivityOptions;
106import android.app.ActivityThread;
107import android.app.AlertDialog;
108import android.app.AppGlobals;
109import android.app.ApplicationErrorReport;
110import android.app.Dialog;
111import android.app.IActivityController;
112import android.app.IApplicationThread;
113import android.app.IInstrumentationWatcher;
114import android.app.INotificationManager;
115import android.app.IProcessObserver;
116import android.app.IServiceConnection;
117import android.app.IStopUserCallback;
118import android.app.IUiAutomationConnection;
119import android.app.IUserSwitchObserver;
120import android.app.Instrumentation;
121import android.app.Notification;
122import android.app.NotificationManager;
123import android.app.PendingIntent;
124import android.app.backup.IBackupManager;
125import android.content.ActivityNotFoundException;
126import android.content.BroadcastReceiver;
127import android.content.ClipData;
128import android.content.ComponentCallbacks2;
129import android.content.ComponentName;
130import android.content.ContentProvider;
131import android.content.ContentResolver;
132import android.content.Context;
133import android.content.DialogInterface;
134import android.content.IContentProvider;
135import android.content.IIntentReceiver;
136import android.content.IIntentSender;
137import android.content.Intent;
138import android.content.IntentFilter;
139import android.content.IntentSender;
140import android.content.pm.ActivityInfo;
141import android.content.pm.ApplicationInfo;
142import android.content.pm.ConfigurationInfo;
143import android.content.pm.IPackageDataObserver;
144import android.content.pm.IPackageManager;
145import android.content.pm.InstrumentationInfo;
146import android.content.pm.PackageInfo;
147import android.content.pm.PackageManager;
148import android.content.pm.ParceledListSlice;
149import android.content.pm.UserInfo;
150import android.content.pm.PackageManager.NameNotFoundException;
151import android.content.pm.PathPermission;
152import android.content.pm.ProviderInfo;
153import android.content.pm.ResolveInfo;
154import android.content.pm.ServiceInfo;
155import android.content.res.CompatibilityInfo;
156import android.content.res.Configuration;
157import android.net.Proxy;
158import android.net.ProxyInfo;
159import android.net.Uri;
160import android.os.Binder;
161import android.os.Build;
162import android.os.Bundle;
163import android.os.Debug;
164import android.os.DropBoxManager;
165import android.os.Environment;
166import android.os.FactoryTest;
167import android.os.FileObserver;
168import android.os.FileUtils;
169import android.os.Handler;
170import android.os.IBinder;
171import android.os.IPermissionController;
172import android.os.IRemoteCallback;
173import android.os.IUserManager;
174import android.os.Looper;
175import android.os.Message;
176import android.os.Parcel;
177import android.os.ParcelFileDescriptor;
178import android.os.PowerManagerInternal;
179import android.os.Process;
180import android.os.RemoteCallbackList;
181import android.os.RemoteException;
182import android.os.SELinux;
183import android.os.ServiceManager;
184import android.os.StrictMode;
185import android.os.SystemClock;
186import android.os.SystemProperties;
187import android.os.UpdateLock;
188import android.os.UserHandle;
189import android.os.UserManager;
190import android.provider.Settings;
191import android.text.format.DateUtils;
192import android.text.format.Time;
193import android.util.AtomicFile;
194import android.util.EventLog;
195import android.util.Log;
196import android.util.Pair;
197import android.util.PrintWriterPrinter;
198import android.util.Slog;
199import android.util.SparseArray;
200import android.util.TimeUtils;
201import android.util.Xml;
202import android.view.Gravity;
203import android.view.LayoutInflater;
204import android.view.View;
205import android.view.WindowManager;
206
207import dalvik.system.VMRuntime;
208
209import java.io.BufferedInputStream;
210import java.io.BufferedOutputStream;
211import java.io.DataInputStream;
212import java.io.DataOutputStream;
213import java.io.File;
214import java.io.FileDescriptor;
215import java.io.FileInputStream;
216import java.io.FileNotFoundException;
217import java.io.FileOutputStream;
218import java.io.IOException;
219import java.io.InputStreamReader;
220import java.io.PrintWriter;
221import java.io.StringWriter;
222import java.lang.ref.WeakReference;
223import java.util.ArrayList;
224import java.util.Arrays;
225import java.util.Collections;
226import java.util.Comparator;
227import java.util.HashMap;
228import java.util.HashSet;
229import java.util.Iterator;
230import java.util.List;
231import java.util.Locale;
232import java.util.Map;
233import java.util.Set;
234import java.util.concurrent.atomic.AtomicBoolean;
235import java.util.concurrent.atomic.AtomicLong;
236
237public final class ActivityManagerService extends ActivityManagerNative
238        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
239
240    private static final String USER_DATA_DIR = "/data/user/";
241    // File that stores last updated system version and called preboot receivers
242    static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat";
243
244    static final String TAG = "ActivityManager";
245    static final String TAG_MU = "ActivityManagerServiceMU";
246    static final boolean DEBUG = false;
247    static final boolean localLOGV = DEBUG;
248    static final boolean DEBUG_BACKUP = localLOGV || false;
249    static final boolean DEBUG_BROADCAST = localLOGV || false;
250    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
251    static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
252    static final boolean DEBUG_CLEANUP = localLOGV || false;
253    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
254    static final boolean DEBUG_FOCUS = false;
255    static final boolean DEBUG_IMMERSIVE = localLOGV || false;
256    static final boolean DEBUG_MU = localLOGV || false;
257    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
258    static final boolean DEBUG_LRU = localLOGV || false;
259    static final boolean DEBUG_PAUSE = localLOGV || false;
260    static final boolean DEBUG_POWER = localLOGV || false;
261    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
262    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
263    static final boolean DEBUG_PROCESSES = localLOGV || false;
264    static final boolean DEBUG_PROVIDER = localLOGV || false;
265    static final boolean DEBUG_RESULTS = localLOGV || false;
266    static final boolean DEBUG_SERVICE = localLOGV || false;
267    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
268    static final boolean DEBUG_STACK = localLOGV || false;
269    static final boolean DEBUG_SWITCH = localLOGV || false;
270    static final boolean DEBUG_TASKS = localLOGV || false;
271    static final boolean DEBUG_THUMBNAILS = localLOGV || false;
272    static final boolean DEBUG_TRANSITION = localLOGV || false;
273    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
274    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
275    static final boolean DEBUG_VISBILITY = localLOGV || false;
276    static final boolean DEBUG_PSS = localLOGV || false;
277    static final boolean DEBUG_LOCKSCREEN = localLOGV || false;
278    static final boolean DEBUG_RECENTS = localLOGV || false;
279    static final boolean VALIDATE_TOKENS = false;
280    static final boolean SHOW_ACTIVITY_START_TIME = true;
281
282    // Control over CPU and battery monitoring.
283    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
284    static final boolean MONITOR_CPU_USAGE = true;
285    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
286    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
287    static final boolean MONITOR_THREAD_CPU_USAGE = false;
288
289    // The flags that are set for all calls we make to the package manager.
290    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
291
292    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
293
294    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
295
296    // Maximum number recent bitmaps to keep in memory.
297    static final int MAX_RECENT_BITMAPS = 3;
298
299    // Amount of time after a call to stopAppSwitches() during which we will
300    // prevent further untrusted switches from happening.
301    static final long APP_SWITCH_DELAY_TIME = 5*1000;
302
303    // How long we wait for a launched process to attach to the activity manager
304    // before we decide it's never going to come up for real.
305    static final int PROC_START_TIMEOUT = 10*1000;
306
307    // How long we wait for a launched process to attach to the activity manager
308    // before we decide it's never going to come up for real, when the process was
309    // started with a wrapper for instrumentation (such as Valgrind) because it
310    // could take much longer than usual.
311    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
312
313    // How long to wait after going idle before forcing apps to GC.
314    static final int GC_TIMEOUT = 5*1000;
315
316    // The minimum amount of time between successive GC requests for a process.
317    static final int GC_MIN_INTERVAL = 60*1000;
318
319    // The minimum amount of time between successive PSS requests for a process.
320    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
321
322    // The minimum amount of time between successive PSS requests for a process
323    // when the request is due to the memory state being lowered.
324    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
325
326    // The rate at which we check for apps using excessive power -- 15 mins.
327    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
328
329    // The minimum sample duration we will allow before deciding we have
330    // enough data on wake locks to start killing things.
331    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
332
333    // The minimum sample duration we will allow before deciding we have
334    // enough data on CPU usage to start killing things.
335    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
336
337    // How long we allow a receiver to run before giving up on it.
338    static final int BROADCAST_FG_TIMEOUT = 10*1000;
339    static final int BROADCAST_BG_TIMEOUT = 60*1000;
340
341    // How long we wait until we timeout on key dispatching.
342    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
343
344    // How long we wait until we timeout on key dispatching during instrumentation.
345    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
346
347    // Amount of time we wait for observers to handle a user switch before
348    // giving up on them and unfreezing the screen.
349    static final int USER_SWITCH_TIMEOUT = 2*1000;
350
351    // Maximum number of users we allow to be running at a time.
352    static final int MAX_RUNNING_USERS = 3;
353
354    // How long to wait in getAssistContextExtras for the activity and foreground services
355    // to respond with the result.
356    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
357
358    // Maximum number of persisted Uri grants a package is allowed
359    static final int MAX_PERSISTED_URI_GRANTS = 128;
360
361    static final int MY_PID = Process.myPid();
362
363    static final String[] EMPTY_STRING_ARRAY = new String[0];
364
365    // How many bytes to write into the dropbox log before truncating
366    static final int DROPBOX_MAX_SIZE = 256 * 1024;
367
368    // Access modes for handleIncomingUser.
369    static final int ALLOW_NON_FULL = 0;
370    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
371    static final int ALLOW_FULL_ONLY = 2;
372
373    static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000;
374
375    // Delay in notifying task stack change listeners (in millis)
376    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 1000;
377
378    /** All system services */
379    SystemServiceManager mSystemServiceManager;
380
381    private Installer mInstaller;
382
383    /** Run all ActivityStacks through this */
384    ActivityStackSupervisor mStackSupervisor;
385
386    /** Task stack change listeners. */
387    private RemoteCallbackList<ITaskStackListener> mTaskStackListeners =
388            new RemoteCallbackList<ITaskStackListener>();
389
390    public IntentFirewall mIntentFirewall;
391
392    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
393    // default actuion automatically.  Important for devices without direct input
394    // devices.
395    private boolean mShowDialogs = true;
396
397    BroadcastQueue mFgBroadcastQueue;
398    BroadcastQueue mBgBroadcastQueue;
399    // Convenient for easy iteration over the queues. Foreground is first
400    // so that dispatch of foreground broadcasts gets precedence.
401    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
402
403    BroadcastQueue broadcastQueueForIntent(Intent intent) {
404        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
405        if (DEBUG_BACKGROUND_BROADCAST) {
406            Slog.i(TAG, "Broadcast intent " + intent + " on "
407                    + (isFg ? "foreground" : "background")
408                    + " queue");
409        }
410        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
411    }
412
413    BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
414        for (BroadcastQueue queue : mBroadcastQueues) {
415            BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
416            if (r != null) {
417                return r;
418            }
419        }
420        return null;
421    }
422
423    /**
424     * Activity we have told the window manager to have key focus.
425     */
426    ActivityRecord mFocusedActivity = null;
427
428    /**
429     * List of intents that were used to start the most recent tasks.
430     */
431    ArrayList<TaskRecord> mRecentTasks;
432    ArrayList<TaskRecord> mTmpRecents = new ArrayList<TaskRecord>();
433
434    /**
435     * For addAppTask: cached of the last activity component that was added.
436     */
437    ComponentName mLastAddedTaskComponent;
438
439    /**
440     * For addAppTask: cached of the last activity uid that was added.
441     */
442    int mLastAddedTaskUid;
443
444    /**
445     * For addAppTask: cached of the last ActivityInfo that was added.
446     */
447    ActivityInfo mLastAddedTaskActivity;
448
449    public class PendingAssistExtras extends Binder implements Runnable {
450        public final ActivityRecord activity;
451        public final Bundle extras;
452        public final Intent intent;
453        public final String hint;
454        public final int userHandle;
455        public boolean haveResult = false;
456        public Bundle result = null;
457        public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
458                String _hint, int _userHandle) {
459            activity = _activity;
460            extras = _extras;
461            intent = _intent;
462            hint = _hint;
463            userHandle = _userHandle;
464        }
465        @Override
466        public void run() {
467            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
468            synchronized (this) {
469                haveResult = true;
470                notifyAll();
471            }
472        }
473    }
474
475    final ArrayList<PendingAssistExtras> mPendingAssistExtras
476            = new ArrayList<PendingAssistExtras>();
477
478    /**
479     * Process management.
480     */
481    final ProcessList mProcessList = new ProcessList();
482
483    /**
484     * All of the applications we currently have running organized by name.
485     * The keys are strings of the application package name (as
486     * returned by the package manager), and the keys are ApplicationRecord
487     * objects.
488     */
489    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
490
491    /**
492     * Tracking long-term execution of processes to look for abuse and other
493     * bad app behavior.
494     */
495    final ProcessStatsService mProcessStats;
496
497    /**
498     * The currently running isolated processes.
499     */
500    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
501
502    /**
503     * Counter for assigning isolated process uids, to avoid frequently reusing the
504     * same ones.
505     */
506    int mNextIsolatedProcessUid = 0;
507
508    /**
509     * The currently running heavy-weight process, if any.
510     */
511    ProcessRecord mHeavyWeightProcess = null;
512
513    /**
514     * The last time that various processes have crashed.
515     */
516    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
517
518    /**
519     * Information about a process that is currently marked as bad.
520     */
521    static final class BadProcessInfo {
522        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
523            this.time = time;
524            this.shortMsg = shortMsg;
525            this.longMsg = longMsg;
526            this.stack = stack;
527        }
528
529        final long time;
530        final String shortMsg;
531        final String longMsg;
532        final String stack;
533    }
534
535    /**
536     * Set of applications that we consider to be bad, and will reject
537     * incoming broadcasts from (which the user has no control over).
538     * Processes are added to this set when they have crashed twice within
539     * a minimum amount of time; they are removed from it when they are
540     * later restarted (hopefully due to some user action).  The value is the
541     * time it was added to the list.
542     */
543    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
544
545    /**
546     * All of the processes we currently have running organized by pid.
547     * The keys are the pid running the application.
548     *
549     * <p>NOTE: This object is protected by its own lock, NOT the global
550     * activity manager lock!
551     */
552    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
553
554    /**
555     * All of the processes that have been forced to be foreground.  The key
556     * is the pid of the caller who requested it (we hold a death
557     * link on it).
558     */
559    abstract class ForegroundToken implements IBinder.DeathRecipient {
560        int pid;
561        IBinder token;
562    }
563    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
564
565    /**
566     * List of records for processes that someone had tried to start before the
567     * system was ready.  We don't start them at that point, but ensure they
568     * are started by the time booting is complete.
569     */
570    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
571
572    /**
573     * List of persistent applications that are in the process
574     * of being started.
575     */
576    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
577
578    /**
579     * Processes that are being forcibly torn down.
580     */
581    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
582
583    /**
584     * List of running applications, sorted by recent usage.
585     * The first entry in the list is the least recently used.
586     */
587    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
588
589    /**
590     * Where in mLruProcesses that the processes hosting activities start.
591     */
592    int mLruProcessActivityStart = 0;
593
594    /**
595     * Where in mLruProcesses that the processes hosting services start.
596     * This is after (lower index) than mLruProcessesActivityStart.
597     */
598    int mLruProcessServiceStart = 0;
599
600    /**
601     * List of processes that should gc as soon as things are idle.
602     */
603    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
604
605    /**
606     * Processes we want to collect PSS data from.
607     */
608    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
609
610    /**
611     * Last time we requested PSS data of all processes.
612     */
613    long mLastFullPssTime = SystemClock.uptimeMillis();
614
615    /**
616     * If set, the next time we collect PSS data we should do a full collection
617     * with data from native processes and the kernel.
618     */
619    boolean mFullPssPending = false;
620
621    /**
622     * This is the process holding what we currently consider to be
623     * the "home" activity.
624     */
625    ProcessRecord mHomeProcess;
626
627    /**
628     * This is the process holding the activity the user last visited that
629     * is in a different process from the one they are currently in.
630     */
631    ProcessRecord mPreviousProcess;
632
633    /**
634     * The time at which the previous process was last visible.
635     */
636    long mPreviousProcessVisibleTime;
637
638    /**
639     * Which uses have been started, so are allowed to run code.
640     */
641    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
642
643    /**
644     * LRU list of history of current users.  Most recently current is at the end.
645     */
646    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
647
648    /**
649     * Constant array of the users that are currently started.
650     */
651    int[] mStartedUserArray = new int[] { 0 };
652
653    /**
654     * Registered observers of the user switching mechanics.
655     */
656    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
657            = new RemoteCallbackList<IUserSwitchObserver>();
658
659    /**
660     * Currently active user switch.
661     */
662    Object mCurUserSwitchCallback;
663
664    /**
665     * Packages that the user has asked to have run in screen size
666     * compatibility mode instead of filling the screen.
667     */
668    final CompatModePackages mCompatModePackages;
669
670    /**
671     * Set of IntentSenderRecord objects that are currently active.
672     */
673    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
674            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
675
676    /**
677     * Fingerprints (hashCode()) of stack traces that we've
678     * already logged DropBox entries for.  Guarded by itself.  If
679     * something (rogue user app) forces this over
680     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
681     */
682    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
683    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
684
685    /**
686     * Strict Mode background batched logging state.
687     *
688     * The string buffer is guarded by itself, and its lock is also
689     * used to determine if another batched write is already
690     * in-flight.
691     */
692    private final StringBuilder mStrictModeBuffer = new StringBuilder();
693
694    /**
695     * Keeps track of all IIntentReceivers that have been registered for
696     * broadcasts.  Hash keys are the receiver IBinder, hash value is
697     * a ReceiverList.
698     */
699    final HashMap<IBinder, ReceiverList> mRegisteredReceivers =
700            new HashMap<IBinder, ReceiverList>();
701
702    /**
703     * Resolver for broadcast intents to registered receivers.
704     * Holds BroadcastFilter (subclass of IntentFilter).
705     */
706    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
707            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
708        @Override
709        protected boolean allowFilterResult(
710                BroadcastFilter filter, List<BroadcastFilter> dest) {
711            IBinder target = filter.receiverList.receiver.asBinder();
712            for (int i=dest.size()-1; i>=0; i--) {
713                if (dest.get(i).receiverList.receiver.asBinder() == target) {
714                    return false;
715                }
716            }
717            return true;
718        }
719
720        @Override
721        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
722            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
723                    || userId == filter.owningUserId) {
724                return super.newResult(filter, match, userId);
725            }
726            return null;
727        }
728
729        @Override
730        protected BroadcastFilter[] newArray(int size) {
731            return new BroadcastFilter[size];
732        }
733
734        @Override
735        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
736            return packageName.equals(filter.packageName);
737        }
738    };
739
740    /**
741     * State of all active sticky broadcasts per user.  Keys are the action of the
742     * sticky Intent, values are an ArrayList of all broadcasted intents with
743     * that action (which should usually be one).  The SparseArray is keyed
744     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
745     * for stickies that are sent to all users.
746     */
747    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
748            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
749
750    final ActiveServices mServices;
751
752    final static class Association {
753        final int mSourceUid;
754        final String mSourceProcess;
755        final int mTargetUid;
756        final ComponentName mTargetComponent;
757        final String mTargetProcess;
758
759        int mCount;
760        long mTime;
761
762        int mNesting;
763        long mStartTime;
764
765        Association(int sourceUid, String sourceProcess, int targetUid,
766                ComponentName targetComponent, String targetProcess) {
767            mSourceUid = sourceUid;
768            mSourceProcess = sourceProcess;
769            mTargetUid = targetUid;
770            mTargetComponent = targetComponent;
771            mTargetProcess = targetProcess;
772        }
773    }
774
775    /**
776     * When service association tracking is enabled, this is all of the associations we
777     * have seen.  Mapping is target uid -> target component -> source uid -> source process name
778     * -> association data.
779     */
780    final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
781            mAssociations = new SparseArray<>();
782    boolean mTrackingAssociations;
783
784    /**
785     * Backup/restore process management
786     */
787    String mBackupAppName = null;
788    BackupRecord mBackupTarget = null;
789
790    final ProviderMap mProviderMap;
791
792    /**
793     * List of content providers who have clients waiting for them.  The
794     * application is currently being launched and the provider will be
795     * removed from this list once it is published.
796     */
797    final ArrayList<ContentProviderRecord> mLaunchingProviders
798            = new ArrayList<ContentProviderRecord>();
799
800    /**
801     * File storing persisted {@link #mGrantedUriPermissions}.
802     */
803    private final AtomicFile mGrantFile;
804
805    /** XML constants used in {@link #mGrantFile} */
806    private static final String TAG_URI_GRANTS = "uri-grants";
807    private static final String TAG_URI_GRANT = "uri-grant";
808    private static final String ATTR_USER_HANDLE = "userHandle";
809    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
810    private static final String ATTR_TARGET_USER_ID = "targetUserId";
811    private static final String ATTR_SOURCE_PKG = "sourcePkg";
812    private static final String ATTR_TARGET_PKG = "targetPkg";
813    private static final String ATTR_URI = "uri";
814    private static final String ATTR_MODE_FLAGS = "modeFlags";
815    private static final String ATTR_CREATED_TIME = "createdTime";
816    private static final String ATTR_PREFIX = "prefix";
817
818    /**
819     * Global set of specific {@link Uri} permissions that have been granted.
820     * This optimized lookup structure maps from {@link UriPermission#targetUid}
821     * to {@link UriPermission#uri} to {@link UriPermission}.
822     */
823    @GuardedBy("this")
824    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
825            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
826
827    public static class GrantUri {
828        public final int sourceUserId;
829        public final Uri uri;
830        public boolean prefix;
831
832        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
833            this.sourceUserId = sourceUserId;
834            this.uri = uri;
835            this.prefix = prefix;
836        }
837
838        @Override
839        public int hashCode() {
840            int hashCode = 1;
841            hashCode = 31 * hashCode + sourceUserId;
842            hashCode = 31 * hashCode + uri.hashCode();
843            hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
844            return hashCode;
845        }
846
847        @Override
848        public boolean equals(Object o) {
849            if (o instanceof GrantUri) {
850                GrantUri other = (GrantUri) o;
851                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
852                        && prefix == other.prefix;
853            }
854            return false;
855        }
856
857        @Override
858        public String toString() {
859            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
860            if (prefix) result += " [prefix]";
861            return result;
862        }
863
864        public String toSafeString() {
865            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
866            if (prefix) result += " [prefix]";
867            return result;
868        }
869
870        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
871            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
872                    ContentProvider.getUriWithoutUserId(uri), false);
873        }
874    }
875
876    CoreSettingsObserver mCoreSettingsObserver;
877
878    /**
879     * Thread-local storage used to carry caller permissions over through
880     * indirect content-provider access.
881     */
882    private class Identity {
883        public final IBinder token;
884        public final int pid;
885        public final int uid;
886
887        Identity(IBinder _token, int _pid, int _uid) {
888            token = _token;
889            pid = _pid;
890            uid = _uid;
891        }
892    }
893
894    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
895
896    /**
897     * All information we have collected about the runtime performance of
898     * any user id that can impact battery performance.
899     */
900    final BatteryStatsService mBatteryStatsService;
901
902    /**
903     * Information about component usage
904     */
905    UsageStatsManagerInternal mUsageStatsService;
906
907    /**
908     * Information about and control over application operations
909     */
910    final AppOpsService mAppOpsService;
911
912    /**
913     * Save recent tasks information across reboots.
914     */
915    final TaskPersister mTaskPersister;
916
917    /**
918     * Current configuration information.  HistoryRecord objects are given
919     * a reference to this object to indicate which configuration they are
920     * currently running in, so this object must be kept immutable.
921     */
922    Configuration mConfiguration = new Configuration();
923
924    /**
925     * Current sequencing integer of the configuration, for skipping old
926     * configurations.
927     */
928    int mConfigurationSeq = 0;
929
930    /**
931     * Hardware-reported OpenGLES version.
932     */
933    final int GL_ES_VERSION;
934
935    /**
936     * List of initialization arguments to pass to all processes when binding applications to them.
937     * For example, references to the commonly used services.
938     */
939    HashMap<String, IBinder> mAppBindArgs;
940
941    /**
942     * Temporary to avoid allocations.  Protected by main lock.
943     */
944    final StringBuilder mStringBuilder = new StringBuilder(256);
945
946    /**
947     * Used to control how we initialize the service.
948     */
949    ComponentName mTopComponent;
950    String mTopAction = Intent.ACTION_MAIN;
951    String mTopData;
952    boolean mProcessesReady = false;
953    boolean mSystemReady = false;
954    boolean mBooting = false;
955    boolean mCallFinishBooting = false;
956    boolean mBootAnimationComplete = false;
957    boolean mWaitingUpdate = false;
958    boolean mDidUpdate = false;
959    boolean mOnBattery = false;
960    boolean mLaunchWarningShown = false;
961
962    Context mContext;
963
964    int mFactoryTest;
965
966    boolean mCheckedForSetup;
967
968    /**
969     * The time at which we will allow normal application switches again,
970     * after a call to {@link #stopAppSwitches()}.
971     */
972    long mAppSwitchesAllowedTime;
973
974    /**
975     * This is set to true after the first switch after mAppSwitchesAllowedTime
976     * is set; any switches after that will clear the time.
977     */
978    boolean mDidAppSwitch;
979
980    /**
981     * Last time (in realtime) at which we checked for power usage.
982     */
983    long mLastPowerCheckRealtime;
984
985    /**
986     * Last time (in uptime) at which we checked for power usage.
987     */
988    long mLastPowerCheckUptime;
989
990    /**
991     * Set while we are wanting to sleep, to prevent any
992     * activities from being started/resumed.
993     */
994    private boolean mSleeping = false;
995
996    /**
997     * Set while we are running a voice interaction.  This overrides
998     * sleeping while it is active.
999     */
1000    private boolean mRunningVoice = false;
1001
1002    /**
1003     * State of external calls telling us if the device is awake or asleep.
1004     */
1005    private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1006
1007    static final int LOCK_SCREEN_HIDDEN = 0;
1008    static final int LOCK_SCREEN_LEAVING = 1;
1009    static final int LOCK_SCREEN_SHOWN = 2;
1010    /**
1011     * State of external call telling us if the lock screen is shown.
1012     */
1013    int mLockScreenShown = LOCK_SCREEN_HIDDEN;
1014
1015    /**
1016     * Set if we are shutting down the system, similar to sleeping.
1017     */
1018    boolean mShuttingDown = false;
1019
1020    /**
1021     * Current sequence id for oom_adj computation traversal.
1022     */
1023    int mAdjSeq = 0;
1024
1025    /**
1026     * Current sequence id for process LRU updating.
1027     */
1028    int mLruSeq = 0;
1029
1030    /**
1031     * Keep track of the non-cached/empty process we last found, to help
1032     * determine how to distribute cached/empty processes next time.
1033     */
1034    int mNumNonCachedProcs = 0;
1035
1036    /**
1037     * Keep track of the number of cached hidden procs, to balance oom adj
1038     * distribution between those and empty procs.
1039     */
1040    int mNumCachedHiddenProcs = 0;
1041
1042    /**
1043     * Keep track of the number of service processes we last found, to
1044     * determine on the next iteration which should be B services.
1045     */
1046    int mNumServiceProcs = 0;
1047    int mNewNumAServiceProcs = 0;
1048    int mNewNumServiceProcs = 0;
1049
1050    /**
1051     * Allow the current computed overall memory level of the system to go down?
1052     * This is set to false when we are killing processes for reasons other than
1053     * memory management, so that the now smaller process list will not be taken as
1054     * an indication that memory is tighter.
1055     */
1056    boolean mAllowLowerMemLevel = false;
1057
1058    /**
1059     * The last computed memory level, for holding when we are in a state that
1060     * processes are going away for other reasons.
1061     */
1062    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1063
1064    /**
1065     * The last total number of process we have, to determine if changes actually look
1066     * like a shrinking number of process due to lower RAM.
1067     */
1068    int mLastNumProcesses;
1069
1070    /**
1071     * The uptime of the last time we performed idle maintenance.
1072     */
1073    long mLastIdleTime = SystemClock.uptimeMillis();
1074
1075    /**
1076     * Total time spent with RAM that has been added in the past since the last idle time.
1077     */
1078    long mLowRamTimeSinceLastIdle = 0;
1079
1080    /**
1081     * If RAM is currently low, when that horrible situation started.
1082     */
1083    long mLowRamStartTime = 0;
1084
1085    /**
1086     * For reporting to battery stats the current top application.
1087     */
1088    private String mCurResumedPackage = null;
1089    private int mCurResumedUid = -1;
1090
1091    /**
1092     * For reporting to battery stats the apps currently running foreground
1093     * service.  The ProcessMap is package/uid tuples; each of these contain
1094     * an array of the currently foreground processes.
1095     */
1096    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1097            = new ProcessMap<ArrayList<ProcessRecord>>();
1098
1099    /**
1100     * This is set if we had to do a delayed dexopt of an app before launching
1101     * it, to increase the ANR timeouts in that case.
1102     */
1103    boolean mDidDexOpt;
1104
1105    /**
1106     * Set if the systemServer made a call to enterSafeMode.
1107     */
1108    boolean mSafeMode;
1109
1110    /**
1111     * If true, we are running under a test environment so will sample PSS from processes
1112     * much more rapidly to try to collect better data when the tests are rapidly
1113     * running through apps.
1114     */
1115    boolean mTestPssMode = false;
1116
1117    String mDebugApp = null;
1118    boolean mWaitForDebugger = false;
1119    boolean mDebugTransient = false;
1120    String mOrigDebugApp = null;
1121    boolean mOrigWaitForDebugger = false;
1122    boolean mAlwaysFinishActivities = false;
1123    IActivityController mController = null;
1124    String mProfileApp = null;
1125    ProcessRecord mProfileProc = null;
1126    String mProfileFile;
1127    ParcelFileDescriptor mProfileFd;
1128    int mSamplingInterval = 0;
1129    boolean mAutoStopProfiler = false;
1130    int mProfileType = 0;
1131    String mOpenGlTraceApp = null;
1132
1133    final long[] mTmpLong = new long[1];
1134
1135    static class ProcessChangeItem {
1136        static final int CHANGE_ACTIVITIES = 1<<0;
1137        static final int CHANGE_PROCESS_STATE = 1<<1;
1138        int changes;
1139        int uid;
1140        int pid;
1141        int processState;
1142        boolean foregroundActivities;
1143    }
1144
1145    final RemoteCallbackList<IProcessObserver> mProcessObservers
1146            = new RemoteCallbackList<IProcessObserver>();
1147    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1148
1149    final ArrayList<ProcessChangeItem> mPendingProcessChanges
1150            = new ArrayList<ProcessChangeItem>();
1151    final ArrayList<ProcessChangeItem> mAvailProcessChanges
1152            = new ArrayList<ProcessChangeItem>();
1153
1154    /**
1155     * Runtime CPU use collection thread.  This object's lock is used to
1156     * perform synchronization with the thread (notifying it to run).
1157     */
1158    final Thread mProcessCpuThread;
1159
1160    /**
1161     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1162     * Must acquire this object's lock when accessing it.
1163     * NOTE: this lock will be held while doing long operations (trawling
1164     * through all processes in /proc), so it should never be acquired by
1165     * any critical paths such as when holding the main activity manager lock.
1166     */
1167    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1168            MONITOR_THREAD_CPU_USAGE);
1169    final AtomicLong mLastCpuTime = new AtomicLong(0);
1170    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1171
1172    long mLastWriteTime = 0;
1173
1174    /**
1175     * Used to retain an update lock when the foreground activity is in
1176     * immersive mode.
1177     */
1178    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1179
1180    /**
1181     * Set to true after the system has finished booting.
1182     */
1183    boolean mBooted = false;
1184
1185    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1186    int mProcessLimitOverride = -1;
1187
1188    WindowManagerService mWindowManager;
1189
1190    final ActivityThread mSystemThread;
1191
1192    // Holds the current foreground user's id
1193    int mCurrentUserId = 0;
1194    // Holds the target user's id during a user switch
1195    int mTargetUserId = UserHandle.USER_NULL;
1196    // If there are multiple profiles for the current user, their ids are here
1197    // Currently only the primary user can have managed profiles
1198    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1199
1200    /**
1201     * Mapping from each known user ID to the profile group ID it is associated with.
1202     */
1203    SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray();
1204
1205    private UserManagerService mUserManager;
1206
1207    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1208        final ProcessRecord mApp;
1209        final int mPid;
1210        final IApplicationThread mAppThread;
1211
1212        AppDeathRecipient(ProcessRecord app, int pid,
1213                IApplicationThread thread) {
1214            if (localLOGV) Slog.v(
1215                TAG, "New death recipient " + this
1216                + " for thread " + thread.asBinder());
1217            mApp = app;
1218            mPid = pid;
1219            mAppThread = thread;
1220        }
1221
1222        @Override
1223        public void binderDied() {
1224            if (localLOGV) Slog.v(
1225                TAG, "Death received in " + this
1226                + " for thread " + mAppThread.asBinder());
1227            synchronized(ActivityManagerService.this) {
1228                appDiedLocked(mApp, mPid, mAppThread);
1229            }
1230        }
1231    }
1232
1233    static final int SHOW_ERROR_MSG = 1;
1234    static final int SHOW_NOT_RESPONDING_MSG = 2;
1235    static final int SHOW_FACTORY_ERROR_MSG = 3;
1236    static final int UPDATE_CONFIGURATION_MSG = 4;
1237    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1238    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1239    static final int SERVICE_TIMEOUT_MSG = 12;
1240    static final int UPDATE_TIME_ZONE = 13;
1241    static final int SHOW_UID_ERROR_MSG = 14;
1242    static final int SHOW_FINGERPRINT_ERROR_MSG = 15;
1243    static final int PROC_START_TIMEOUT_MSG = 20;
1244    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1245    static final int KILL_APPLICATION_MSG = 22;
1246    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1247    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1248    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1249    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1250    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1251    static final int CLEAR_DNS_CACHE_MSG = 28;
1252    static final int UPDATE_HTTP_PROXY_MSG = 29;
1253    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1254    static final int DISPATCH_PROCESSES_CHANGED = 31;
1255    static final int DISPATCH_PROCESS_DIED = 32;
1256    static final int REPORT_MEM_USAGE_MSG = 33;
1257    static final int REPORT_USER_SWITCH_MSG = 34;
1258    static final int CONTINUE_USER_SWITCH_MSG = 35;
1259    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1260    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1261    static final int PERSIST_URI_GRANTS_MSG = 38;
1262    static final int REQUEST_ALL_PSS_MSG = 39;
1263    static final int START_PROFILES_MSG = 40;
1264    static final int UPDATE_TIME = 41;
1265    static final int SYSTEM_USER_START_MSG = 42;
1266    static final int SYSTEM_USER_CURRENT_MSG = 43;
1267    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1268    static final int FINISH_BOOTING_MSG = 45;
1269    static final int START_USER_SWITCH_MSG = 46;
1270    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1271    static final int DISMISS_DIALOG_MSG = 48;
1272    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49;
1273
1274    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1275    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1276    static final int FIRST_COMPAT_MODE_MSG = 300;
1277    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1278
1279    CompatModeDialog mCompatModeDialog;
1280    long mLastMemUsageReportTime = 0;
1281
1282    /**
1283     * Flag whether the current user is a "monkey", i.e. whether
1284     * the UI is driven by a UI automation tool.
1285     */
1286    private boolean mUserIsMonkey;
1287
1288    /** Flag whether the device has a Recents UI */
1289    boolean mHasRecents;
1290
1291    /** The dimensions of the thumbnails in the Recents UI. */
1292    int mThumbnailWidth;
1293    int mThumbnailHeight;
1294
1295    final ServiceThread mHandlerThread;
1296    final MainHandler mHandler;
1297
1298    final class MainHandler extends Handler {
1299        public MainHandler(Looper looper) {
1300            super(looper, null, true);
1301        }
1302
1303        @Override
1304        public void handleMessage(Message msg) {
1305            switch (msg.what) {
1306            case SHOW_ERROR_MSG: {
1307                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1308                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1309                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1310                synchronized (ActivityManagerService.this) {
1311                    ProcessRecord proc = (ProcessRecord)data.get("app");
1312                    AppErrorResult res = (AppErrorResult) data.get("result");
1313                    if (proc != null && proc.crashDialog != null) {
1314                        Slog.e(TAG, "App already has crash dialog: " + proc);
1315                        if (res != null) {
1316                            res.set(0);
1317                        }
1318                        return;
1319                    }
1320                    boolean isBackground = (UserHandle.getAppId(proc.uid)
1321                            >= Process.FIRST_APPLICATION_UID
1322                            && proc.pid != MY_PID);
1323                    for (int userId : mCurrentProfileIds) {
1324                        isBackground &= (proc.userId != userId);
1325                    }
1326                    if (isBackground && !showBackground) {
1327                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1328                        if (res != null) {
1329                            res.set(0);
1330                        }
1331                        return;
1332                    }
1333                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1334                        Dialog d = new AppErrorDialog(mContext,
1335                                ActivityManagerService.this, res, proc);
1336                        d.show();
1337                        proc.crashDialog = d;
1338                    } else {
1339                        // The device is asleep, so just pretend that the user
1340                        // saw a crash dialog and hit "force quit".
1341                        if (res != null) {
1342                            res.set(0);
1343                        }
1344                    }
1345                }
1346
1347                ensureBootCompleted();
1348            } break;
1349            case SHOW_NOT_RESPONDING_MSG: {
1350                synchronized (ActivityManagerService.this) {
1351                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1352                    ProcessRecord proc = (ProcessRecord)data.get("app");
1353                    if (proc != null && proc.anrDialog != null) {
1354                        Slog.e(TAG, "App already has anr dialog: " + proc);
1355                        return;
1356                    }
1357
1358                    Intent intent = new Intent("android.intent.action.ANR");
1359                    if (!mProcessesReady) {
1360                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1361                                | Intent.FLAG_RECEIVER_FOREGROUND);
1362                    }
1363                    broadcastIntentLocked(null, null, intent,
1364                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1365                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1366
1367                    if (mShowDialogs) {
1368                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1369                                mContext, proc, (ActivityRecord)data.get("activity"),
1370                                msg.arg1 != 0);
1371                        d.show();
1372                        proc.anrDialog = d;
1373                    } else {
1374                        // Just kill the app if there is no dialog to be shown.
1375                        killAppAtUsersRequest(proc, null);
1376                    }
1377                }
1378
1379                ensureBootCompleted();
1380            } break;
1381            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1382                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1383                synchronized (ActivityManagerService.this) {
1384                    ProcessRecord proc = (ProcessRecord) data.get("app");
1385                    if (proc == null) {
1386                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1387                        break;
1388                    }
1389                    if (proc.crashDialog != null) {
1390                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1391                        return;
1392                    }
1393                    AppErrorResult res = (AppErrorResult) data.get("result");
1394                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1395                        Dialog d = new StrictModeViolationDialog(mContext,
1396                                ActivityManagerService.this, res, proc);
1397                        d.show();
1398                        proc.crashDialog = d;
1399                    } else {
1400                        // The device is asleep, so just pretend that the user
1401                        // saw a crash dialog and hit "force quit".
1402                        res.set(0);
1403                    }
1404                }
1405                ensureBootCompleted();
1406            } break;
1407            case SHOW_FACTORY_ERROR_MSG: {
1408                Dialog d = new FactoryErrorDialog(
1409                    mContext, msg.getData().getCharSequence("msg"));
1410                d.show();
1411                ensureBootCompleted();
1412            } break;
1413            case UPDATE_CONFIGURATION_MSG: {
1414                final ContentResolver resolver = mContext.getContentResolver();
1415                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1416            } break;
1417            case GC_BACKGROUND_PROCESSES_MSG: {
1418                synchronized (ActivityManagerService.this) {
1419                    performAppGcsIfAppropriateLocked();
1420                }
1421            } break;
1422            case WAIT_FOR_DEBUGGER_MSG: {
1423                synchronized (ActivityManagerService.this) {
1424                    ProcessRecord app = (ProcessRecord)msg.obj;
1425                    if (msg.arg1 != 0) {
1426                        if (!app.waitedForDebugger) {
1427                            Dialog d = new AppWaitingForDebuggerDialog(
1428                                    ActivityManagerService.this,
1429                                    mContext, app);
1430                            app.waitDialog = d;
1431                            app.waitedForDebugger = true;
1432                            d.show();
1433                        }
1434                    } else {
1435                        if (app.waitDialog != null) {
1436                            app.waitDialog.dismiss();
1437                            app.waitDialog = null;
1438                        }
1439                    }
1440                }
1441            } break;
1442            case SERVICE_TIMEOUT_MSG: {
1443                if (mDidDexOpt) {
1444                    mDidDexOpt = false;
1445                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1446                    nmsg.obj = msg.obj;
1447                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1448                    return;
1449                }
1450                mServices.serviceTimeout((ProcessRecord)msg.obj);
1451            } break;
1452            case UPDATE_TIME_ZONE: {
1453                synchronized (ActivityManagerService.this) {
1454                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1455                        ProcessRecord r = mLruProcesses.get(i);
1456                        if (r.thread != null) {
1457                            try {
1458                                r.thread.updateTimeZone();
1459                            } catch (RemoteException ex) {
1460                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1461                            }
1462                        }
1463                    }
1464                }
1465            } break;
1466            case CLEAR_DNS_CACHE_MSG: {
1467                synchronized (ActivityManagerService.this) {
1468                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1469                        ProcessRecord r = mLruProcesses.get(i);
1470                        if (r.thread != null) {
1471                            try {
1472                                r.thread.clearDnsCache();
1473                            } catch (RemoteException ex) {
1474                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1475                            }
1476                        }
1477                    }
1478                }
1479            } break;
1480            case UPDATE_HTTP_PROXY_MSG: {
1481                ProxyInfo proxy = (ProxyInfo)msg.obj;
1482                String host = "";
1483                String port = "";
1484                String exclList = "";
1485                Uri pacFileUrl = Uri.EMPTY;
1486                if (proxy != null) {
1487                    host = proxy.getHost();
1488                    port = Integer.toString(proxy.getPort());
1489                    exclList = proxy.getExclusionListAsString();
1490                    pacFileUrl = proxy.getPacFileUrl();
1491                }
1492                synchronized (ActivityManagerService.this) {
1493                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1494                        ProcessRecord r = mLruProcesses.get(i);
1495                        if (r.thread != null) {
1496                            try {
1497                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1498                            } catch (RemoteException ex) {
1499                                Slog.w(TAG, "Failed to update http proxy for: " +
1500                                        r.info.processName);
1501                            }
1502                        }
1503                    }
1504                }
1505            } break;
1506            case SHOW_UID_ERROR_MSG: {
1507                if (mShowDialogs) {
1508                    AlertDialog d = new BaseErrorDialog(mContext);
1509                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1510                    d.setCancelable(false);
1511                    d.setTitle(mContext.getText(R.string.android_system_label));
1512                    d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1513                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1514                            mHandler.obtainMessage(DISMISS_DIALOG_MSG, d));
1515                    d.show();
1516                }
1517            } break;
1518            case SHOW_FINGERPRINT_ERROR_MSG: {
1519                if (mShowDialogs) {
1520                    AlertDialog d = new BaseErrorDialog(mContext);
1521                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1522                    d.setCancelable(false);
1523                    d.setTitle(mContext.getText(R.string.android_system_label));
1524                    d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1525                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1526                            mHandler.obtainMessage(DISMISS_DIALOG_MSG, d));
1527                    d.show();
1528                }
1529            } break;
1530            case PROC_START_TIMEOUT_MSG: {
1531                if (mDidDexOpt) {
1532                    mDidDexOpt = false;
1533                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1534                    nmsg.obj = msg.obj;
1535                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1536                    return;
1537                }
1538                ProcessRecord app = (ProcessRecord)msg.obj;
1539                synchronized (ActivityManagerService.this) {
1540                    processStartTimedOutLocked(app);
1541                }
1542            } break;
1543            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1544                synchronized (ActivityManagerService.this) {
1545                    mStackSupervisor.doPendingActivityLaunchesLocked(true);
1546                }
1547            } break;
1548            case KILL_APPLICATION_MSG: {
1549                synchronized (ActivityManagerService.this) {
1550                    int appid = msg.arg1;
1551                    boolean restart = (msg.arg2 == 1);
1552                    Bundle bundle = (Bundle)msg.obj;
1553                    String pkg = bundle.getString("pkg");
1554                    String reason = bundle.getString("reason");
1555                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1556                            false, UserHandle.USER_ALL, reason);
1557                }
1558            } break;
1559            case FINALIZE_PENDING_INTENT_MSG: {
1560                ((PendingIntentRecord)msg.obj).completeFinalize();
1561            } break;
1562            case POST_HEAVY_NOTIFICATION_MSG: {
1563                INotificationManager inm = NotificationManager.getService();
1564                if (inm == null) {
1565                    return;
1566                }
1567
1568                ActivityRecord root = (ActivityRecord)msg.obj;
1569                ProcessRecord process = root.app;
1570                if (process == null) {
1571                    return;
1572                }
1573
1574                try {
1575                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1576                    String text = mContext.getString(R.string.heavy_weight_notification,
1577                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1578                    Notification notification = new Notification();
1579                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1580                    notification.when = 0;
1581                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1582                    notification.tickerText = text;
1583                    notification.defaults = 0; // please be quiet
1584                    notification.sound = null;
1585                    notification.vibrate = null;
1586                    notification.color = mContext.getResources().getColor(
1587                            com.android.internal.R.color.system_notification_accent_color);
1588                    notification.setLatestEventInfo(context, text,
1589                            mContext.getText(R.string.heavy_weight_notification_detail),
1590                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1591                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1592                                    new UserHandle(root.userId)));
1593
1594                    try {
1595                        int[] outId = new int[1];
1596                        inm.enqueueNotificationWithTag("android", "android", null,
1597                                R.string.heavy_weight_notification,
1598                                notification, outId, root.userId);
1599                    } catch (RuntimeException e) {
1600                        Slog.w(ActivityManagerService.TAG,
1601                                "Error showing notification for heavy-weight app", e);
1602                    } catch (RemoteException e) {
1603                    }
1604                } catch (NameNotFoundException e) {
1605                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1606                }
1607            } break;
1608            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1609                INotificationManager inm = NotificationManager.getService();
1610                if (inm == null) {
1611                    return;
1612                }
1613                try {
1614                    inm.cancelNotificationWithTag("android", null,
1615                            R.string.heavy_weight_notification,  msg.arg1);
1616                } catch (RuntimeException e) {
1617                    Slog.w(ActivityManagerService.TAG,
1618                            "Error canceling notification for service", e);
1619                } catch (RemoteException e) {
1620                }
1621            } break;
1622            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1623                synchronized (ActivityManagerService.this) {
1624                    checkExcessivePowerUsageLocked(true);
1625                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1626                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1627                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1628                }
1629            } break;
1630            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1631                synchronized (ActivityManagerService.this) {
1632                    ActivityRecord ar = (ActivityRecord)msg.obj;
1633                    if (mCompatModeDialog != null) {
1634                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1635                                ar.info.applicationInfo.packageName)) {
1636                            return;
1637                        }
1638                        mCompatModeDialog.dismiss();
1639                        mCompatModeDialog = null;
1640                    }
1641                    if (ar != null && false) {
1642                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1643                                ar.packageName)) {
1644                            int mode = mCompatModePackages.computeCompatModeLocked(
1645                                    ar.info.applicationInfo);
1646                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1647                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1648                                mCompatModeDialog = new CompatModeDialog(
1649                                        ActivityManagerService.this, mContext,
1650                                        ar.info.applicationInfo);
1651                                mCompatModeDialog.show();
1652                            }
1653                        }
1654                    }
1655                }
1656                break;
1657            }
1658            case DISPATCH_PROCESSES_CHANGED: {
1659                dispatchProcessesChanged();
1660                break;
1661            }
1662            case DISPATCH_PROCESS_DIED: {
1663                final int pid = msg.arg1;
1664                final int uid = msg.arg2;
1665                dispatchProcessDied(pid, uid);
1666                break;
1667            }
1668            case REPORT_MEM_USAGE_MSG: {
1669                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1670                Thread thread = new Thread() {
1671                    @Override public void run() {
1672                        reportMemUsage(memInfos);
1673                    }
1674                };
1675                thread.start();
1676                break;
1677            }
1678            case START_USER_SWITCH_MSG: {
1679                showUserSwitchDialog(msg.arg1, (String) msg.obj);
1680                break;
1681            }
1682            case REPORT_USER_SWITCH_MSG: {
1683                dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1684                break;
1685            }
1686            case CONTINUE_USER_SWITCH_MSG: {
1687                continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1688                break;
1689            }
1690            case USER_SWITCH_TIMEOUT_MSG: {
1691                timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1692                break;
1693            }
1694            case IMMERSIVE_MODE_LOCK_MSG: {
1695                final boolean nextState = (msg.arg1 != 0);
1696                if (mUpdateLock.isHeld() != nextState) {
1697                    if (DEBUG_IMMERSIVE) {
1698                        final ActivityRecord r = (ActivityRecord) msg.obj;
1699                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1700                    }
1701                    if (nextState) {
1702                        mUpdateLock.acquire();
1703                    } else {
1704                        mUpdateLock.release();
1705                    }
1706                }
1707                break;
1708            }
1709            case PERSIST_URI_GRANTS_MSG: {
1710                writeGrantedUriPermissions();
1711                break;
1712            }
1713            case REQUEST_ALL_PSS_MSG: {
1714                synchronized (ActivityManagerService.this) {
1715                    requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1716                }
1717                break;
1718            }
1719            case START_PROFILES_MSG: {
1720                synchronized (ActivityManagerService.this) {
1721                    startProfilesLocked();
1722                }
1723                break;
1724            }
1725            case UPDATE_TIME: {
1726                synchronized (ActivityManagerService.this) {
1727                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1728                        ProcessRecord r = mLruProcesses.get(i);
1729                        if (r.thread != null) {
1730                            try {
1731                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1732                            } catch (RemoteException ex) {
1733                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1734                            }
1735                        }
1736                    }
1737                }
1738                break;
1739            }
1740            case SYSTEM_USER_START_MSG: {
1741                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1742                        Integer.toString(msg.arg1), msg.arg1);
1743                mSystemServiceManager.startUser(msg.arg1);
1744                break;
1745            }
1746            case SYSTEM_USER_CURRENT_MSG: {
1747                mBatteryStatsService.noteEvent(
1748                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1749                        Integer.toString(msg.arg2), msg.arg2);
1750                mBatteryStatsService.noteEvent(
1751                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1752                        Integer.toString(msg.arg1), msg.arg1);
1753                mSystemServiceManager.switchUser(msg.arg1);
1754                break;
1755            }
1756            case ENTER_ANIMATION_COMPLETE_MSG: {
1757                synchronized (ActivityManagerService.this) {
1758                    ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj);
1759                    if (r != null && r.app != null && r.app.thread != null) {
1760                        try {
1761                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1762                        } catch (RemoteException e) {
1763                        }
1764                    }
1765                }
1766                break;
1767            }
1768            case FINISH_BOOTING_MSG: {
1769                if (msg.arg1 != 0) {
1770                    finishBooting();
1771                }
1772                if (msg.arg2 != 0) {
1773                    enableScreenAfterBoot();
1774                }
1775                break;
1776            }
1777            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
1778                try {
1779                    Locale l = (Locale) msg.obj;
1780                    IBinder service = ServiceManager.getService("mount");
1781                    IMountService mountService = IMountService.Stub.asInterface(service);
1782                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
1783                    mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
1784                } catch (RemoteException e) {
1785                    Log.e(TAG, "Error storing locale for decryption UI", e);
1786                }
1787                break;
1788            }
1789            case DISMISS_DIALOG_MSG: {
1790                final Dialog d = (Dialog) msg.obj;
1791                d.dismiss();
1792                break;
1793            }
1794            case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: {
1795                synchronized (ActivityManagerService.this) {
1796                    int i = mTaskStackListeners.beginBroadcast();
1797                    while (i > 0) {
1798                        i--;
1799                        try {
1800                            // Make a one-way callback to the listener
1801                            mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged();
1802                        } catch (RemoteException e){
1803                            // Handled by the RemoteCallbackList
1804                        }
1805                    }
1806                    mTaskStackListeners.finishBroadcast();
1807                }
1808                break;
1809            }
1810            }
1811        }
1812    };
1813
1814    static final int COLLECT_PSS_BG_MSG = 1;
1815
1816    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1817        @Override
1818        public void handleMessage(Message msg) {
1819            switch (msg.what) {
1820            case COLLECT_PSS_BG_MSG: {
1821                long start = SystemClock.uptimeMillis();
1822                MemInfoReader memInfo = null;
1823                synchronized (ActivityManagerService.this) {
1824                    if (mFullPssPending) {
1825                        mFullPssPending = false;
1826                        memInfo = new MemInfoReader();
1827                    }
1828                }
1829                if (memInfo != null) {
1830                    updateCpuStatsNow();
1831                    long nativeTotalPss = 0;
1832                    synchronized (mProcessCpuTracker) {
1833                        final int N = mProcessCpuTracker.countStats();
1834                        for (int j=0; j<N; j++) {
1835                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
1836                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
1837                                // This is definitely an application process; skip it.
1838                                continue;
1839                            }
1840                            synchronized (mPidsSelfLocked) {
1841                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
1842                                    // This is one of our own processes; skip it.
1843                                    continue;
1844                                }
1845                            }
1846                            nativeTotalPss += Debug.getPss(st.pid, null, null);
1847                        }
1848                    }
1849                    memInfo.readMemInfo();
1850                    synchronized (ActivityManagerService.this) {
1851                        if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in "
1852                                + (SystemClock.uptimeMillis()-start) + "ms");
1853                        mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
1854                                memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
1855                                memInfo.getKernelUsedSizeKb(), nativeTotalPss);
1856                    }
1857                }
1858
1859                int num = 0;
1860                long[] tmp = new long[1];
1861                do {
1862                    ProcessRecord proc;
1863                    int procState;
1864                    int pid;
1865                    long lastPssTime;
1866                    synchronized (ActivityManagerService.this) {
1867                        if (mPendingPssProcesses.size() <= 0) {
1868                            if (mTestPssMode || DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num
1869                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1870                            mPendingPssProcesses.clear();
1871                            return;
1872                        }
1873                        proc = mPendingPssProcesses.remove(0);
1874                        procState = proc.pssProcState;
1875                        lastPssTime = proc.lastPssTime;
1876                        if (proc.thread != null && procState == proc.setProcState
1877                                && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
1878                                        < SystemClock.uptimeMillis()) {
1879                            pid = proc.pid;
1880                        } else {
1881                            proc = null;
1882                            pid = 0;
1883                        }
1884                    }
1885                    if (proc != null) {
1886                        long pss = Debug.getPss(pid, tmp, null);
1887                        synchronized (ActivityManagerService.this) {
1888                            if (pss != 0 && proc.thread != null && proc.setProcState == procState
1889                                    && proc.pid == pid && proc.lastPssTime == lastPssTime) {
1890                                num++;
1891                                recordPssSample(proc, procState, pss, tmp[0],
1892                                        SystemClock.uptimeMillis());
1893                            }
1894                        }
1895                    }
1896                } while (true);
1897            }
1898            }
1899        }
1900    };
1901
1902    public void setSystemProcess() {
1903        try {
1904            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
1905            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
1906            ServiceManager.addService("meminfo", new MemBinder(this));
1907            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
1908            ServiceManager.addService("dbinfo", new DbBinder(this));
1909            if (MONITOR_CPU_USAGE) {
1910                ServiceManager.addService("cpuinfo", new CpuBinder(this));
1911            }
1912            ServiceManager.addService("permission", new PermissionController(this));
1913
1914            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
1915                    "android", STOCK_PM_FLAGS);
1916            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
1917
1918            synchronized (this) {
1919                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
1920                app.persistent = true;
1921                app.pid = MY_PID;
1922                app.maxAdj = ProcessList.SYSTEM_ADJ;
1923                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
1924                mProcessNames.put(app.processName, app.uid, app);
1925                synchronized (mPidsSelfLocked) {
1926                    mPidsSelfLocked.put(app.pid, app);
1927                }
1928                updateLruProcessLocked(app, false, null);
1929                updateOomAdjLocked();
1930            }
1931        } catch (PackageManager.NameNotFoundException e) {
1932            throw new RuntimeException(
1933                    "Unable to find android system package", e);
1934        }
1935    }
1936
1937    public void setWindowManager(WindowManagerService wm) {
1938        mWindowManager = wm;
1939        mStackSupervisor.setWindowManager(wm);
1940    }
1941
1942    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
1943        mUsageStatsService = usageStatsManager;
1944    }
1945
1946    public void startObservingNativeCrashes() {
1947        final NativeCrashListener ncl = new NativeCrashListener(this);
1948        ncl.start();
1949    }
1950
1951    public IAppOpsService getAppOpsService() {
1952        return mAppOpsService;
1953    }
1954
1955    static class MemBinder extends Binder {
1956        ActivityManagerService mActivityManagerService;
1957        MemBinder(ActivityManagerService activityManagerService) {
1958            mActivityManagerService = activityManagerService;
1959        }
1960
1961        @Override
1962        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1963            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1964                    != PackageManager.PERMISSION_GRANTED) {
1965                pw.println("Permission Denial: can't dump meminfo from from pid="
1966                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1967                        + " without permission " + android.Manifest.permission.DUMP);
1968                return;
1969            }
1970
1971            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
1972        }
1973    }
1974
1975    static class GraphicsBinder extends Binder {
1976        ActivityManagerService mActivityManagerService;
1977        GraphicsBinder(ActivityManagerService activityManagerService) {
1978            mActivityManagerService = activityManagerService;
1979        }
1980
1981        @Override
1982        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1983            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1984                    != PackageManager.PERMISSION_GRANTED) {
1985                pw.println("Permission Denial: can't dump gfxinfo from from pid="
1986                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1987                        + " without permission " + android.Manifest.permission.DUMP);
1988                return;
1989            }
1990
1991            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
1992        }
1993    }
1994
1995    static class DbBinder extends Binder {
1996        ActivityManagerService mActivityManagerService;
1997        DbBinder(ActivityManagerService activityManagerService) {
1998            mActivityManagerService = activityManagerService;
1999        }
2000
2001        @Override
2002        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2003            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2004                    != PackageManager.PERMISSION_GRANTED) {
2005                pw.println("Permission Denial: can't dump dbinfo from from pid="
2006                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2007                        + " without permission " + android.Manifest.permission.DUMP);
2008                return;
2009            }
2010
2011            mActivityManagerService.dumpDbInfo(fd, pw, args);
2012        }
2013    }
2014
2015    static class CpuBinder extends Binder {
2016        ActivityManagerService mActivityManagerService;
2017        CpuBinder(ActivityManagerService activityManagerService) {
2018            mActivityManagerService = activityManagerService;
2019        }
2020
2021        @Override
2022        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2023            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2024                    != PackageManager.PERMISSION_GRANTED) {
2025                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2026                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2027                        + " without permission " + android.Manifest.permission.DUMP);
2028                return;
2029            }
2030
2031            synchronized (mActivityManagerService.mProcessCpuTracker) {
2032                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2033                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2034                        SystemClock.uptimeMillis()));
2035            }
2036        }
2037    }
2038
2039    public static final class Lifecycle extends SystemService {
2040        private final ActivityManagerService mService;
2041
2042        public Lifecycle(Context context) {
2043            super(context);
2044            mService = new ActivityManagerService(context);
2045        }
2046
2047        @Override
2048        public void onStart() {
2049            mService.start();
2050        }
2051
2052        public ActivityManagerService getService() {
2053            return mService;
2054        }
2055    }
2056
2057    // Note: This method is invoked on the main thread but may need to attach various
2058    // handlers to other threads.  So take care to be explicit about the looper.
2059    public ActivityManagerService(Context systemContext) {
2060        mContext = systemContext;
2061        mFactoryTest = FactoryTest.getMode();
2062        mSystemThread = ActivityThread.currentActivityThread();
2063
2064        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2065
2066        mHandlerThread = new ServiceThread(TAG,
2067                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2068        mHandlerThread.start();
2069        mHandler = new MainHandler(mHandlerThread.getLooper());
2070
2071        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2072                "foreground", BROADCAST_FG_TIMEOUT, false);
2073        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2074                "background", BROADCAST_BG_TIMEOUT, true);
2075        mBroadcastQueues[0] = mFgBroadcastQueue;
2076        mBroadcastQueues[1] = mBgBroadcastQueue;
2077
2078        mServices = new ActiveServices(this);
2079        mProviderMap = new ProviderMap(this);
2080
2081        // TODO: Move creation of battery stats service outside of activity manager service.
2082        File dataDir = Environment.getDataDirectory();
2083        File systemDir = new File(dataDir, "system");
2084        systemDir.mkdirs();
2085        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2086        mBatteryStatsService.getActiveStatistics().readLocked();
2087        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2088        mOnBattery = DEBUG_POWER ? true
2089                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2090        mBatteryStatsService.getActiveStatistics().setCallback(this);
2091
2092        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2093
2094        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2095
2096        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2097
2098        // User 0 is the first and only user that runs at boot.
2099        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2100        mUserLru.add(Integer.valueOf(0));
2101        updateStartedUserArrayLocked();
2102
2103        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2104            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2105
2106        mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2107
2108        mConfiguration.setToDefaults();
2109        mConfiguration.locale = Locale.getDefault();
2110
2111        mConfigurationSeq = mConfiguration.seq = 1;
2112        mProcessCpuTracker.init();
2113
2114        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2115        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2116        mStackSupervisor = new ActivityStackSupervisor(this);
2117        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor);
2118
2119        mProcessCpuThread = new Thread("CpuTracker") {
2120            @Override
2121            public void run() {
2122                while (true) {
2123                    try {
2124                        try {
2125                            synchronized(this) {
2126                                final long now = SystemClock.uptimeMillis();
2127                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2128                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2129                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2130                                //        + ", write delay=" + nextWriteDelay);
2131                                if (nextWriteDelay < nextCpuDelay) {
2132                                    nextCpuDelay = nextWriteDelay;
2133                                }
2134                                if (nextCpuDelay > 0) {
2135                                    mProcessCpuMutexFree.set(true);
2136                                    this.wait(nextCpuDelay);
2137                                }
2138                            }
2139                        } catch (InterruptedException e) {
2140                        }
2141                        updateCpuStatsNow();
2142                    } catch (Exception e) {
2143                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2144                    }
2145                }
2146            }
2147        };
2148
2149        Watchdog.getInstance().addMonitor(this);
2150        Watchdog.getInstance().addThread(mHandler);
2151    }
2152
2153    public void setSystemServiceManager(SystemServiceManager mgr) {
2154        mSystemServiceManager = mgr;
2155    }
2156
2157    public void setInstaller(Installer installer) {
2158        mInstaller = installer;
2159    }
2160
2161    private void start() {
2162        Process.removeAllProcessGroups();
2163        mProcessCpuThread.start();
2164
2165        mBatteryStatsService.publish(mContext);
2166        mAppOpsService.publish(mContext);
2167        Slog.d("AppOps", "AppOpsService published");
2168        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2169    }
2170
2171    public void initPowerManagement() {
2172        mStackSupervisor.initPowerManagement();
2173        mBatteryStatsService.initPowerManagement();
2174    }
2175
2176    @Override
2177    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2178            throws RemoteException {
2179        if (code == SYSPROPS_TRANSACTION) {
2180            // We need to tell all apps about the system property change.
2181            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2182            synchronized(this) {
2183                final int NP = mProcessNames.getMap().size();
2184                for (int ip=0; ip<NP; ip++) {
2185                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2186                    final int NA = apps.size();
2187                    for (int ia=0; ia<NA; ia++) {
2188                        ProcessRecord app = apps.valueAt(ia);
2189                        if (app.thread != null) {
2190                            procs.add(app.thread.asBinder());
2191                        }
2192                    }
2193                }
2194            }
2195
2196            int N = procs.size();
2197            for (int i=0; i<N; i++) {
2198                Parcel data2 = Parcel.obtain();
2199                try {
2200                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2201                } catch (RemoteException e) {
2202                }
2203                data2.recycle();
2204            }
2205        }
2206        try {
2207            return super.onTransact(code, data, reply, flags);
2208        } catch (RuntimeException e) {
2209            // The activity manager only throws security exceptions, so let's
2210            // log all others.
2211            if (!(e instanceof SecurityException)) {
2212                Slog.wtf(TAG, "Activity Manager Crash", e);
2213            }
2214            throw e;
2215        }
2216    }
2217
2218    void updateCpuStats() {
2219        final long now = SystemClock.uptimeMillis();
2220        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2221            return;
2222        }
2223        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2224            synchronized (mProcessCpuThread) {
2225                mProcessCpuThread.notify();
2226            }
2227        }
2228    }
2229
2230    void updateCpuStatsNow() {
2231        synchronized (mProcessCpuTracker) {
2232            mProcessCpuMutexFree.set(false);
2233            final long now = SystemClock.uptimeMillis();
2234            boolean haveNewCpuStats = false;
2235
2236            if (MONITOR_CPU_USAGE &&
2237                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2238                mLastCpuTime.set(now);
2239                haveNewCpuStats = true;
2240                mProcessCpuTracker.update();
2241                //Slog.i(TAG, mProcessCpu.printCurrentState());
2242                //Slog.i(TAG, "Total CPU usage: "
2243                //        + mProcessCpu.getTotalCpuPercent() + "%");
2244
2245                // Slog the cpu usage if the property is set.
2246                if ("true".equals(SystemProperties.get("events.cpu"))) {
2247                    int user = mProcessCpuTracker.getLastUserTime();
2248                    int system = mProcessCpuTracker.getLastSystemTime();
2249                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2250                    int irq = mProcessCpuTracker.getLastIrqTime();
2251                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2252                    int idle = mProcessCpuTracker.getLastIdleTime();
2253
2254                    int total = user + system + iowait + irq + softIrq + idle;
2255                    if (total == 0) total = 1;
2256
2257                    EventLog.writeEvent(EventLogTags.CPU,
2258                            ((user+system+iowait+irq+softIrq) * 100) / total,
2259                            (user * 100) / total,
2260                            (system * 100) / total,
2261                            (iowait * 100) / total,
2262                            (irq * 100) / total,
2263                            (softIrq * 100) / total);
2264                }
2265            }
2266
2267            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2268            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2269            synchronized(bstats) {
2270                synchronized(mPidsSelfLocked) {
2271                    if (haveNewCpuStats) {
2272                        if (mOnBattery) {
2273                            int perc = bstats.startAddingCpuLocked();
2274                            int totalUTime = 0;
2275                            int totalSTime = 0;
2276                            final int N = mProcessCpuTracker.countStats();
2277                            for (int i=0; i<N; i++) {
2278                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2279                                if (!st.working) {
2280                                    continue;
2281                                }
2282                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2283                                int otherUTime = (st.rel_utime*perc)/100;
2284                                int otherSTime = (st.rel_stime*perc)/100;
2285                                totalUTime += otherUTime;
2286                                totalSTime += otherSTime;
2287                                if (pr != null) {
2288                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2289                                    if (ps == null || !ps.isActive()) {
2290                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2291                                                pr.info.uid, pr.processName);
2292                                    }
2293                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2294                                            st.rel_stime-otherSTime);
2295                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2296                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2297                                } else {
2298                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2299                                    if (ps == null || !ps.isActive()) {
2300                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2301                                                bstats.mapUid(st.uid), st.name);
2302                                    }
2303                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2304                                            st.rel_stime-otherSTime);
2305                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2306                                }
2307                            }
2308                            bstats.finishAddingCpuLocked(perc, totalUTime,
2309                                    totalSTime, cpuSpeedTimes);
2310                        }
2311                    }
2312                }
2313
2314                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2315                    mLastWriteTime = now;
2316                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2317                }
2318            }
2319        }
2320    }
2321
2322    @Override
2323    public void batteryNeedsCpuUpdate() {
2324        updateCpuStatsNow();
2325    }
2326
2327    @Override
2328    public void batteryPowerChanged(boolean onBattery) {
2329        // When plugging in, update the CPU stats first before changing
2330        // the plug state.
2331        updateCpuStatsNow();
2332        synchronized (this) {
2333            synchronized(mPidsSelfLocked) {
2334                mOnBattery = DEBUG_POWER ? true : onBattery;
2335            }
2336        }
2337    }
2338
2339    /**
2340     * Initialize the application bind args. These are passed to each
2341     * process when the bindApplication() IPC is sent to the process. They're
2342     * lazily setup to make sure the services are running when they're asked for.
2343     */
2344    private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2345        if (mAppBindArgs == null) {
2346            mAppBindArgs = new HashMap<>();
2347
2348            // Isolated processes won't get this optimization, so that we don't
2349            // violate the rules about which services they have access to.
2350            if (!isolated) {
2351                // Setup the application init args
2352                mAppBindArgs.put("package", ServiceManager.getService("package"));
2353                mAppBindArgs.put("window", ServiceManager.getService("window"));
2354                mAppBindArgs.put(Context.ALARM_SERVICE,
2355                        ServiceManager.getService(Context.ALARM_SERVICE));
2356            }
2357        }
2358        return mAppBindArgs;
2359    }
2360
2361    final void setFocusedActivityLocked(ActivityRecord r) {
2362        if (mFocusedActivity != r) {
2363            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2364            mFocusedActivity = r;
2365            if (r.task != null && r.task.voiceInteractor != null) {
2366                startRunningVoiceLocked();
2367            } else {
2368                finishRunningVoiceLocked();
2369            }
2370            mStackSupervisor.setFocusedStack(r);
2371            if (r != null) {
2372                mWindowManager.setFocusedApp(r.appToken, true);
2373            }
2374            applyUpdateLockStateLocked(r);
2375        }
2376    }
2377
2378    final void clearFocusedActivity(ActivityRecord r) {
2379        if (mFocusedActivity == r) {
2380            mFocusedActivity = null;
2381        }
2382    }
2383
2384    @Override
2385    public void setFocusedStack(int stackId) {
2386        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2387        synchronized (ActivityManagerService.this) {
2388            ActivityStack stack = mStackSupervisor.getStack(stackId);
2389            if (stack != null) {
2390                ActivityRecord r = stack.topRunningActivityLocked(null);
2391                if (r != null) {
2392                    setFocusedActivityLocked(r);
2393                }
2394            }
2395        }
2396    }
2397
2398    /** Sets the task stack listener that gets callbacks when a task stack changes. */
2399    @Override
2400    public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
2401        synchronized (ActivityManagerService.this) {
2402            if (listener != null) {
2403                mTaskStackListeners.register(listener);
2404            }
2405        }
2406    }
2407
2408    @Override
2409    public void notifyActivityDrawn(IBinder token) {
2410        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2411        synchronized (this) {
2412            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2413            if (r != null) {
2414                r.task.stack.notifyActivityDrawnLocked(r);
2415            }
2416        }
2417    }
2418
2419    final void applyUpdateLockStateLocked(ActivityRecord r) {
2420        // Modifications to the UpdateLock state are done on our handler, outside
2421        // the activity manager's locks.  The new state is determined based on the
2422        // state *now* of the relevant activity record.  The object is passed to
2423        // the handler solely for logging detail, not to be consulted/modified.
2424        final boolean nextState = r != null && r.immersive;
2425        mHandler.sendMessage(
2426                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2427    }
2428
2429    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2430        Message msg = Message.obtain();
2431        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2432        msg.obj = r.task.askedCompatMode ? null : r;
2433        mHandler.sendMessage(msg);
2434    }
2435
2436    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2437            String what, Object obj, ProcessRecord srcApp) {
2438        app.lastActivityTime = now;
2439
2440        if (app.activities.size() > 0) {
2441            // Don't want to touch dependent processes that are hosting activities.
2442            return index;
2443        }
2444
2445        int lrui = mLruProcesses.lastIndexOf(app);
2446        if (lrui < 0) {
2447            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2448                    + what + " " + obj + " from " + srcApp);
2449            return index;
2450        }
2451
2452        if (lrui >= index) {
2453            // Don't want to cause this to move dependent processes *back* in the
2454            // list as if they were less frequently used.
2455            return index;
2456        }
2457
2458        if (lrui >= mLruProcessActivityStart) {
2459            // Don't want to touch dependent processes that are hosting activities.
2460            return index;
2461        }
2462
2463        mLruProcesses.remove(lrui);
2464        if (index > 0) {
2465            index--;
2466        }
2467        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2468                + " in LRU list: " + app);
2469        mLruProcesses.add(index, app);
2470        return index;
2471    }
2472
2473    final void removeLruProcessLocked(ProcessRecord app) {
2474        int lrui = mLruProcesses.lastIndexOf(app);
2475        if (lrui >= 0) {
2476            if (!app.killed) {
2477                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
2478                Process.killProcessQuiet(app.pid);
2479                Process.killProcessGroup(app.info.uid, app.pid);
2480            }
2481            if (lrui <= mLruProcessActivityStart) {
2482                mLruProcessActivityStart--;
2483            }
2484            if (lrui <= mLruProcessServiceStart) {
2485                mLruProcessServiceStart--;
2486            }
2487            mLruProcesses.remove(lrui);
2488        }
2489    }
2490
2491    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2492            ProcessRecord client) {
2493        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2494                || app.treatLikeActivity;
2495        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2496        if (!activityChange && hasActivity) {
2497            // The process has activities, so we are only allowing activity-based adjustments
2498            // to move it.  It should be kept in the front of the list with other
2499            // processes that have activities, and we don't want those to change their
2500            // order except due to activity operations.
2501            return;
2502        }
2503
2504        mLruSeq++;
2505        final long now = SystemClock.uptimeMillis();
2506        app.lastActivityTime = now;
2507
2508        // First a quick reject: if the app is already at the position we will
2509        // put it, then there is nothing to do.
2510        if (hasActivity) {
2511            final int N = mLruProcesses.size();
2512            if (N > 0 && mLruProcesses.get(N-1) == app) {
2513                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2514                return;
2515            }
2516        } else {
2517            if (mLruProcessServiceStart > 0
2518                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2519                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2520                return;
2521            }
2522        }
2523
2524        int lrui = mLruProcesses.lastIndexOf(app);
2525
2526        if (app.persistent && lrui >= 0) {
2527            // We don't care about the position of persistent processes, as long as
2528            // they are in the list.
2529            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2530            return;
2531        }
2532
2533        /* In progress: compute new position first, so we can avoid doing work
2534           if the process is not actually going to move.  Not yet working.
2535        int addIndex;
2536        int nextIndex;
2537        boolean inActivity = false, inService = false;
2538        if (hasActivity) {
2539            // Process has activities, put it at the very tipsy-top.
2540            addIndex = mLruProcesses.size();
2541            nextIndex = mLruProcessServiceStart;
2542            inActivity = true;
2543        } else if (hasService) {
2544            // Process has services, put it at the top of the service list.
2545            addIndex = mLruProcessActivityStart;
2546            nextIndex = mLruProcessServiceStart;
2547            inActivity = true;
2548            inService = true;
2549        } else  {
2550            // Process not otherwise of interest, it goes to the top of the non-service area.
2551            addIndex = mLruProcessServiceStart;
2552            if (client != null) {
2553                int clientIndex = mLruProcesses.lastIndexOf(client);
2554                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2555                        + app);
2556                if (clientIndex >= 0 && addIndex > clientIndex) {
2557                    addIndex = clientIndex;
2558                }
2559            }
2560            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2561        }
2562
2563        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2564                + mLruProcessActivityStart + "): " + app);
2565        */
2566
2567        if (lrui >= 0) {
2568            if (lrui < mLruProcessActivityStart) {
2569                mLruProcessActivityStart--;
2570            }
2571            if (lrui < mLruProcessServiceStart) {
2572                mLruProcessServiceStart--;
2573            }
2574            /*
2575            if (addIndex > lrui) {
2576                addIndex--;
2577            }
2578            if (nextIndex > lrui) {
2579                nextIndex--;
2580            }
2581            */
2582            mLruProcesses.remove(lrui);
2583        }
2584
2585        /*
2586        mLruProcesses.add(addIndex, app);
2587        if (inActivity) {
2588            mLruProcessActivityStart++;
2589        }
2590        if (inService) {
2591            mLruProcessActivityStart++;
2592        }
2593        */
2594
2595        int nextIndex;
2596        if (hasActivity) {
2597            final int N = mLruProcesses.size();
2598            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2599                // Process doesn't have activities, but has clients with
2600                // activities...  move it up, but one below the top (the top
2601                // should always have a real activity).
2602                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2603                mLruProcesses.add(N-1, app);
2604                // To keep it from spamming the LRU list (by making a bunch of clients),
2605                // we will push down any other entries owned by the app.
2606                final int uid = app.info.uid;
2607                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2608                    ProcessRecord subProc = mLruProcesses.get(i);
2609                    if (subProc.info.uid == uid) {
2610                        // We want to push this one down the list.  If the process after
2611                        // it is for the same uid, however, don't do so, because we don't
2612                        // want them internally to be re-ordered.
2613                        if (mLruProcesses.get(i-1).info.uid != uid) {
2614                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2615                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2616                            ProcessRecord tmp = mLruProcesses.get(i);
2617                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2618                            mLruProcesses.set(i-1, tmp);
2619                            i--;
2620                        }
2621                    } else {
2622                        // A gap, we can stop here.
2623                        break;
2624                    }
2625                }
2626            } else {
2627                // Process has activities, put it at the very tipsy-top.
2628                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2629                mLruProcesses.add(app);
2630            }
2631            nextIndex = mLruProcessServiceStart;
2632        } else if (hasService) {
2633            // Process has services, put it at the top of the service list.
2634            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2635            mLruProcesses.add(mLruProcessActivityStart, app);
2636            nextIndex = mLruProcessServiceStart;
2637            mLruProcessActivityStart++;
2638        } else  {
2639            // Process not otherwise of interest, it goes to the top of the non-service area.
2640            int index = mLruProcessServiceStart;
2641            if (client != null) {
2642                // If there is a client, don't allow the process to be moved up higher
2643                // in the list than that client.
2644                int clientIndex = mLruProcesses.lastIndexOf(client);
2645                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2646                        + " when updating " + app);
2647                if (clientIndex <= lrui) {
2648                    // Don't allow the client index restriction to push it down farther in the
2649                    // list than it already is.
2650                    clientIndex = lrui;
2651                }
2652                if (clientIndex >= 0 && index > clientIndex) {
2653                    index = clientIndex;
2654                }
2655            }
2656            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2657            mLruProcesses.add(index, app);
2658            nextIndex = index-1;
2659            mLruProcessActivityStart++;
2660            mLruProcessServiceStart++;
2661        }
2662
2663        // If the app is currently using a content provider or service,
2664        // bump those processes as well.
2665        for (int j=app.connections.size()-1; j>=0; j--) {
2666            ConnectionRecord cr = app.connections.valueAt(j);
2667            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2668                    && cr.binding.service.app != null
2669                    && cr.binding.service.app.lruSeq != mLruSeq
2670                    && !cr.binding.service.app.persistent) {
2671                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2672                        "service connection", cr, app);
2673            }
2674        }
2675        for (int j=app.conProviders.size()-1; j>=0; j--) {
2676            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2677            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2678                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2679                        "provider reference", cpr, app);
2680            }
2681        }
2682    }
2683
2684    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2685        if (uid == Process.SYSTEM_UID) {
2686            // The system gets to run in any process.  If there are multiple
2687            // processes with the same uid, just pick the first (this
2688            // should never happen).
2689            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2690            if (procs == null) return null;
2691            final int N = procs.size();
2692            for (int i = 0; i < N; i++) {
2693                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2694            }
2695        }
2696        ProcessRecord proc = mProcessNames.get(processName, uid);
2697        if (false && proc != null && !keepIfLarge
2698                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2699                && proc.lastCachedPss >= 4000) {
2700            // Turn this condition on to cause killing to happen regularly, for testing.
2701            if (proc.baseProcessTracker != null) {
2702                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2703            }
2704            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2705        } else if (proc != null && !keepIfLarge
2706                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2707                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2708            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2709            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2710                if (proc.baseProcessTracker != null) {
2711                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2712                }
2713                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2714            }
2715        }
2716        return proc;
2717    }
2718
2719    void ensurePackageDexOpt(String packageName) {
2720        IPackageManager pm = AppGlobals.getPackageManager();
2721        try {
2722            if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) {
2723                mDidDexOpt = true;
2724            }
2725        } catch (RemoteException e) {
2726        }
2727    }
2728
2729    boolean isNextTransitionForward() {
2730        int transit = mWindowManager.getPendingAppTransition();
2731        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2732                || transit == AppTransition.TRANSIT_TASK_OPEN
2733                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2734    }
2735
2736    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
2737            String processName, String abiOverride, int uid, Runnable crashHandler) {
2738        synchronized(this) {
2739            ApplicationInfo info = new ApplicationInfo();
2740            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
2741            // For isolated processes, the former contains the parent's uid and the latter the
2742            // actual uid of the isolated process.
2743            // In the special case introduced by this method (which is, starting an isolated
2744            // process directly from the SystemServer without an actual parent app process) the
2745            // closest thing to a parent's uid is SYSTEM_UID.
2746            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
2747            // the |isolated| logic in the ProcessRecord constructor.
2748            info.uid = Process.SYSTEM_UID;
2749            info.processName = processName;
2750            info.className = entryPoint;
2751            info.packageName = "android";
2752            ProcessRecord proc = startProcessLocked(processName, info /* info */,
2753                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
2754                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
2755                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
2756                    crashHandler);
2757            return proc != null ? proc.pid : 0;
2758        }
2759    }
2760
2761    final ProcessRecord startProcessLocked(String processName,
2762            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2763            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2764            boolean isolated, boolean keepIfLarge) {
2765        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
2766                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
2767                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
2768                null /* crashHandler */);
2769    }
2770
2771    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
2772            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
2773            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
2774            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
2775        long startTime = SystemClock.elapsedRealtime();
2776        ProcessRecord app;
2777        if (!isolated) {
2778            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2779            checkTime(startTime, "startProcess: after getProcessRecord");
2780        } else {
2781            // If this is an isolated process, it can't re-use an existing process.
2782            app = null;
2783        }
2784        // We don't have to do anything more if:
2785        // (1) There is an existing application record; and
2786        // (2) The caller doesn't think it is dead, OR there is no thread
2787        //     object attached to it so we know it couldn't have crashed; and
2788        // (3) There is a pid assigned to it, so it is either starting or
2789        //     already running.
2790        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2791                + " app=" + app + " knownToBeDead=" + knownToBeDead
2792                + " thread=" + (app != null ? app.thread : null)
2793                + " pid=" + (app != null ? app.pid : -1));
2794        if (app != null && app.pid > 0) {
2795            if (!knownToBeDead || app.thread == null) {
2796                // We already have the app running, or are waiting for it to
2797                // come up (we have a pid but not yet its thread), so keep it.
2798                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2799                // If this is a new package in the process, add the package to the list
2800                app.addPackage(info.packageName, info.versionCode, mProcessStats);
2801                checkTime(startTime, "startProcess: done, added package to proc");
2802                return app;
2803            }
2804
2805            // An application record is attached to a previous process,
2806            // clean it up now.
2807            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2808            checkTime(startTime, "startProcess: bad proc running, killing");
2809            Process.killProcessGroup(app.info.uid, app.pid);
2810            handleAppDiedLocked(app, true, true);
2811            checkTime(startTime, "startProcess: done killing old proc");
2812        }
2813
2814        String hostingNameStr = hostingName != null
2815                ? hostingName.flattenToShortString() : null;
2816
2817        if (!isolated) {
2818            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2819                // If we are in the background, then check to see if this process
2820                // is bad.  If so, we will just silently fail.
2821                if (mBadProcesses.get(info.processName, info.uid) != null) {
2822                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2823                            + "/" + info.processName);
2824                    return null;
2825                }
2826            } else {
2827                // When the user is explicitly starting a process, then clear its
2828                // crash count so that we won't make it bad until they see at
2829                // least one crash dialog again, and make the process good again
2830                // if it had been bad.
2831                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2832                        + "/" + info.processName);
2833                mProcessCrashTimes.remove(info.processName, info.uid);
2834                if (mBadProcesses.get(info.processName, info.uid) != null) {
2835                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2836                            UserHandle.getUserId(info.uid), info.uid,
2837                            info.processName);
2838                    mBadProcesses.remove(info.processName, info.uid);
2839                    if (app != null) {
2840                        app.bad = false;
2841                    }
2842                }
2843            }
2844        }
2845
2846        if (app == null) {
2847            checkTime(startTime, "startProcess: creating new process record");
2848            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
2849            if (app == null) {
2850                Slog.w(TAG, "Failed making new process record for "
2851                        + processName + "/" + info.uid + " isolated=" + isolated);
2852                return null;
2853            }
2854            app.crashHandler = crashHandler;
2855            mProcessNames.put(processName, app.uid, app);
2856            if (isolated) {
2857                mIsolatedProcesses.put(app.uid, app);
2858            }
2859            checkTime(startTime, "startProcess: done creating new process record");
2860        } else {
2861            // If this is a new package in the process, add the package to the list
2862            app.addPackage(info.packageName, info.versionCode, mProcessStats);
2863            checkTime(startTime, "startProcess: added package to existing proc");
2864        }
2865
2866        // If the system is not ready yet, then hold off on starting this
2867        // process until it is.
2868        if (!mProcessesReady
2869                && !isAllowedWhileBooting(info)
2870                && !allowWhileBooting) {
2871            if (!mProcessesOnHold.contains(app)) {
2872                mProcessesOnHold.add(app);
2873            }
2874            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2875            checkTime(startTime, "startProcess: returning with proc on hold");
2876            return app;
2877        }
2878
2879        checkTime(startTime, "startProcess: stepping in to startProcess");
2880        startProcessLocked(
2881                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
2882        checkTime(startTime, "startProcess: done starting proc!");
2883        return (app.pid != 0) ? app : null;
2884    }
2885
2886    boolean isAllowedWhileBooting(ApplicationInfo ai) {
2887        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2888    }
2889
2890    private final void startProcessLocked(ProcessRecord app,
2891            String hostingType, String hostingNameStr) {
2892        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
2893                null /* entryPoint */, null /* entryPointArgs */);
2894    }
2895
2896    private final void startProcessLocked(ProcessRecord app, String hostingType,
2897            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
2898        long startTime = SystemClock.elapsedRealtime();
2899        if (app.pid > 0 && app.pid != MY_PID) {
2900            checkTime(startTime, "startProcess: removing from pids map");
2901            synchronized (mPidsSelfLocked) {
2902                mPidsSelfLocked.remove(app.pid);
2903                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2904            }
2905            checkTime(startTime, "startProcess: done removing from pids map");
2906            app.setPid(0);
2907        }
2908
2909        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2910                "startProcessLocked removing on hold: " + app);
2911        mProcessesOnHold.remove(app);
2912
2913        checkTime(startTime, "startProcess: starting to update cpu stats");
2914        updateCpuStats();
2915        checkTime(startTime, "startProcess: done updating cpu stats");
2916
2917        try {
2918            int uid = app.uid;
2919
2920            int[] gids = null;
2921            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2922            if (!app.isolated) {
2923                int[] permGids = null;
2924                try {
2925                    checkTime(startTime, "startProcess: getting gids from package manager");
2926                    final PackageManager pm = mContext.getPackageManager();
2927                    permGids = pm.getPackageGids(app.info.packageName);
2928
2929                    if (Environment.isExternalStorageEmulated()) {
2930                        checkTime(startTime, "startProcess: checking external storage perm");
2931                        if (pm.checkPermission(
2932                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2933                                app.info.packageName) == PERMISSION_GRANTED) {
2934                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2935                        } else {
2936                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2937                        }
2938                    }
2939                } catch (PackageManager.NameNotFoundException e) {
2940                    Slog.w(TAG, "Unable to retrieve gids", e);
2941                }
2942
2943                /*
2944                 * Add shared application and profile GIDs so applications can share some
2945                 * resources like shared libraries and access user-wide resources
2946                 */
2947                if (permGids == null) {
2948                    gids = new int[2];
2949                } else {
2950                    gids = new int[permGids.length + 2];
2951                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
2952                }
2953                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
2954                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
2955            }
2956            checkTime(startTime, "startProcess: building args");
2957            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
2958                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2959                        && mTopComponent != null
2960                        && app.processName.equals(mTopComponent.getPackageName())) {
2961                    uid = 0;
2962                }
2963                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
2964                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2965                    uid = 0;
2966                }
2967            }
2968            int debugFlags = 0;
2969            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2970                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2971                // Also turn on CheckJNI for debuggable apps. It's quite
2972                // awkward to turn on otherwise.
2973                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2974            }
2975            // Run the app in safe mode if its manifest requests so or the
2976            // system is booted in safe mode.
2977            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2978                mSafeMode == true) {
2979                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2980            }
2981            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2982                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2983            }
2984            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2985                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
2986            }
2987            if ("1".equals(SystemProperties.get("debug.assert"))) {
2988                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2989            }
2990
2991            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
2992            if (requiredAbi == null) {
2993                requiredAbi = Build.SUPPORTED_ABIS[0];
2994            }
2995
2996            String instructionSet = null;
2997            if (app.info.primaryCpuAbi != null) {
2998                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
2999            }
3000
3001            app.gids = gids;
3002            app.requiredAbi = requiredAbi;
3003            app.instructionSet = instructionSet;
3004
3005            // Start the process.  It will either succeed and return a result containing
3006            // the PID of the new process, or else throw a RuntimeException.
3007            boolean isActivityProcess = (entryPoint == null);
3008            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3009            checkTime(startTime, "startProcess: asking zygote to start proc");
3010            Process.ProcessStartResult startResult = Process.start(entryPoint,
3011                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3012                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3013                    app.info.dataDir, entryPointArgs);
3014            checkTime(startTime, "startProcess: returned from zygote!");
3015
3016            if (app.isolated) {
3017                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3018            }
3019            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3020            checkTime(startTime, "startProcess: done updating battery stats");
3021
3022            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3023                    UserHandle.getUserId(uid), startResult.pid, uid,
3024                    app.processName, hostingType,
3025                    hostingNameStr != null ? hostingNameStr : "");
3026
3027            if (app.persistent) {
3028                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3029            }
3030
3031            checkTime(startTime, "startProcess: building log message");
3032            StringBuilder buf = mStringBuilder;
3033            buf.setLength(0);
3034            buf.append("Start proc ");
3035            buf.append(startResult.pid);
3036            buf.append(':');
3037            buf.append(app.processName);
3038            buf.append('/');
3039            UserHandle.formatUid(buf, uid);
3040            if (!isActivityProcess) {
3041                buf.append(" [");
3042                buf.append(entryPoint);
3043                buf.append("]");
3044            }
3045            buf.append(" for ");
3046            buf.append(hostingType);
3047            if (hostingNameStr != null) {
3048                buf.append(" ");
3049                buf.append(hostingNameStr);
3050            }
3051            Slog.i(TAG, buf.toString());
3052            app.setPid(startResult.pid);
3053            app.usingWrapper = startResult.usingWrapper;
3054            app.removed = false;
3055            app.killed = false;
3056            app.killedByAm = false;
3057            checkTime(startTime, "startProcess: starting to update pids map");
3058            synchronized (mPidsSelfLocked) {
3059                this.mPidsSelfLocked.put(startResult.pid, app);
3060                if (isActivityProcess) {
3061                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3062                    msg.obj = app;
3063                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3064                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3065                }
3066            }
3067            checkTime(startTime, "startProcess: done updating pids map");
3068        } catch (RuntimeException e) {
3069            // XXX do better error recovery.
3070            app.setPid(0);
3071            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3072            if (app.isolated) {
3073                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3074            }
3075            Slog.e(TAG, "Failure starting process " + app.processName, e);
3076        }
3077    }
3078
3079    void updateUsageStats(ActivityRecord component, boolean resumed) {
3080        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
3081        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3082        if (resumed) {
3083            if (mUsageStatsService != null) {
3084                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3085                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3086            }
3087            synchronized (stats) {
3088                stats.noteActivityResumedLocked(component.app.uid);
3089            }
3090        } else {
3091            if (mUsageStatsService != null) {
3092                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3093                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3094            }
3095            synchronized (stats) {
3096                stats.noteActivityPausedLocked(component.app.uid);
3097            }
3098        }
3099    }
3100
3101    Intent getHomeIntent() {
3102        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3103        intent.setComponent(mTopComponent);
3104        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3105            intent.addCategory(Intent.CATEGORY_HOME);
3106        }
3107        return intent;
3108    }
3109
3110    boolean startHomeActivityLocked(int userId) {
3111        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3112                && mTopAction == null) {
3113            // We are running in factory test mode, but unable to find
3114            // the factory test app, so just sit around displaying the
3115            // error message and don't try to start anything.
3116            return false;
3117        }
3118        Intent intent = getHomeIntent();
3119        ActivityInfo aInfo =
3120            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3121        if (aInfo != null) {
3122            intent.setComponent(new ComponentName(
3123                    aInfo.applicationInfo.packageName, aInfo.name));
3124            // Don't do this if the home app is currently being
3125            // instrumented.
3126            aInfo = new ActivityInfo(aInfo);
3127            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3128            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3129                    aInfo.applicationInfo.uid, true);
3130            if (app == null || app.instrumentationClass == null) {
3131                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3132                mStackSupervisor.startHomeActivity(intent, aInfo);
3133            }
3134        }
3135
3136        return true;
3137    }
3138
3139    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3140        ActivityInfo ai = null;
3141        ComponentName comp = intent.getComponent();
3142        try {
3143            if (comp != null) {
3144                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3145            } else {
3146                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3147                        intent,
3148                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3149                            flags, userId);
3150
3151                if (info != null) {
3152                    ai = info.activityInfo;
3153                }
3154            }
3155        } catch (RemoteException e) {
3156            // ignore
3157        }
3158
3159        return ai;
3160    }
3161
3162    /**
3163     * Starts the "new version setup screen" if appropriate.
3164     */
3165    void startSetupActivityLocked() {
3166        // Only do this once per boot.
3167        if (mCheckedForSetup) {
3168            return;
3169        }
3170
3171        // We will show this screen if the current one is a different
3172        // version than the last one shown, and we are not running in
3173        // low-level factory test mode.
3174        final ContentResolver resolver = mContext.getContentResolver();
3175        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3176                Settings.Global.getInt(resolver,
3177                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3178            mCheckedForSetup = true;
3179
3180            // See if we should be showing the platform update setup UI.
3181            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3182            List<ResolveInfo> ris = mContext.getPackageManager()
3183                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3184
3185            // We don't allow third party apps to replace this.
3186            ResolveInfo ri = null;
3187            for (int i=0; ris != null && i<ris.size(); i++) {
3188                if ((ris.get(i).activityInfo.applicationInfo.flags
3189                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3190                    ri = ris.get(i);
3191                    break;
3192                }
3193            }
3194
3195            if (ri != null) {
3196                String vers = ri.activityInfo.metaData != null
3197                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3198                        : null;
3199                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3200                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3201                            Intent.METADATA_SETUP_VERSION);
3202                }
3203                String lastVers = Settings.Secure.getString(
3204                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3205                if (vers != null && !vers.equals(lastVers)) {
3206                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3207                    intent.setComponent(new ComponentName(
3208                            ri.activityInfo.packageName, ri.activityInfo.name));
3209                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3210                            null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, null, null,
3211                            null);
3212                }
3213            }
3214        }
3215    }
3216
3217    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3218        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3219    }
3220
3221    void enforceNotIsolatedCaller(String caller) {
3222        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3223            throw new SecurityException("Isolated process not allowed to call " + caller);
3224        }
3225    }
3226
3227    void enforceShellRestriction(String restriction, int userHandle) {
3228        if (Binder.getCallingUid() == Process.SHELL_UID) {
3229            if (userHandle < 0
3230                    || mUserManager.hasUserRestriction(restriction, userHandle)) {
3231                throw new SecurityException("Shell does not have permission to access user "
3232                        + userHandle);
3233            }
3234        }
3235    }
3236
3237    @Override
3238    public int getFrontActivityScreenCompatMode() {
3239        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3240        synchronized (this) {
3241            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3242        }
3243    }
3244
3245    @Override
3246    public void setFrontActivityScreenCompatMode(int mode) {
3247        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3248                "setFrontActivityScreenCompatMode");
3249        synchronized (this) {
3250            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3251        }
3252    }
3253
3254    @Override
3255    public int getPackageScreenCompatMode(String packageName) {
3256        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3257        synchronized (this) {
3258            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3259        }
3260    }
3261
3262    @Override
3263    public void setPackageScreenCompatMode(String packageName, int mode) {
3264        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3265                "setPackageScreenCompatMode");
3266        synchronized (this) {
3267            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3268        }
3269    }
3270
3271    @Override
3272    public boolean getPackageAskScreenCompat(String packageName) {
3273        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3274        synchronized (this) {
3275            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3276        }
3277    }
3278
3279    @Override
3280    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3281        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3282                "setPackageAskScreenCompat");
3283        synchronized (this) {
3284            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3285        }
3286    }
3287
3288    private void dispatchProcessesChanged() {
3289        int N;
3290        synchronized (this) {
3291            N = mPendingProcessChanges.size();
3292            if (mActiveProcessChanges.length < N) {
3293                mActiveProcessChanges = new ProcessChangeItem[N];
3294            }
3295            mPendingProcessChanges.toArray(mActiveProcessChanges);
3296            mAvailProcessChanges.addAll(mPendingProcessChanges);
3297            mPendingProcessChanges.clear();
3298            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3299        }
3300
3301        int i = mProcessObservers.beginBroadcast();
3302        while (i > 0) {
3303            i--;
3304            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3305            if (observer != null) {
3306                try {
3307                    for (int j=0; j<N; j++) {
3308                        ProcessChangeItem item = mActiveProcessChanges[j];
3309                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3310                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3311                                    + item.pid + " uid=" + item.uid + ": "
3312                                    + item.foregroundActivities);
3313                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3314                                    item.foregroundActivities);
3315                        }
3316                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3317                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3318                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
3319                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3320                        }
3321                    }
3322                } catch (RemoteException e) {
3323                }
3324            }
3325        }
3326        mProcessObservers.finishBroadcast();
3327    }
3328
3329    private void dispatchProcessDied(int pid, int uid) {
3330        int i = mProcessObservers.beginBroadcast();
3331        while (i > 0) {
3332            i--;
3333            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3334            if (observer != null) {
3335                try {
3336                    observer.onProcessDied(pid, uid);
3337                } catch (RemoteException e) {
3338                }
3339            }
3340        }
3341        mProcessObservers.finishBroadcast();
3342    }
3343
3344    @Override
3345    public final int startActivity(IApplicationThread caller, String callingPackage,
3346            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3347            int startFlags, ProfilerInfo profilerInfo, Bundle options) {
3348        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3349            resultWho, requestCode, startFlags, profilerInfo, options,
3350            UserHandle.getCallingUserId());
3351    }
3352
3353    @Override
3354    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3355            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3356            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3357        enforceNotIsolatedCaller("startActivity");
3358        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3359                false, ALLOW_FULL_ONLY, "startActivity", null);
3360        // TODO: Switch to user app stacks here.
3361        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3362                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3363                profilerInfo, null, null, options, userId, null, null);
3364    }
3365
3366    @Override
3367    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
3368            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3369            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3370
3371        // This is very dangerous -- it allows you to perform a start activity (including
3372        // permission grants) as any app that may launch one of your own activities.  So
3373        // we will only allow this to be done from activities that are part of the core framework,
3374        // and then only when they are running as the system.
3375        final ActivityRecord sourceRecord;
3376        final int targetUid;
3377        final String targetPackage;
3378        synchronized (this) {
3379            if (resultTo == null) {
3380                throw new SecurityException("Must be called from an activity");
3381            }
3382            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
3383            if (sourceRecord == null) {
3384                throw new SecurityException("Called with bad activity token: " + resultTo);
3385            }
3386            if (!sourceRecord.info.packageName.equals("android")) {
3387                throw new SecurityException(
3388                        "Must be called from an activity that is declared in the android package");
3389            }
3390            if (sourceRecord.app == null) {
3391                throw new SecurityException("Called without a process attached to activity");
3392            }
3393            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
3394                // This is still okay, as long as this activity is running under the
3395                // uid of the original calling activity.
3396                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
3397                    throw new SecurityException(
3398                            "Calling activity in uid " + sourceRecord.app.uid
3399                                    + " must be system uid or original calling uid "
3400                                    + sourceRecord.launchedFromUid);
3401                }
3402            }
3403            targetUid = sourceRecord.launchedFromUid;
3404            targetPackage = sourceRecord.launchedFromPackage;
3405        }
3406
3407        if (userId == UserHandle.USER_NULL) {
3408            userId = UserHandle.getUserId(sourceRecord.app.uid);
3409        }
3410
3411        // TODO: Switch to user app stacks here.
3412        try {
3413            int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent,
3414                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
3415                    null, null, options, userId, null, null);
3416            return ret;
3417        } catch (SecurityException e) {
3418            // XXX need to figure out how to propagate to original app.
3419            // A SecurityException here is generally actually a fault of the original
3420            // calling activity (such as a fairly granting permissions), so propagate it
3421            // back to them.
3422            /*
3423            StringBuilder msg = new StringBuilder();
3424            msg.append("While launching");
3425            msg.append(intent.toString());
3426            msg.append(": ");
3427            msg.append(e.getMessage());
3428            */
3429            throw e;
3430        }
3431    }
3432
3433    @Override
3434    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3435            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3436            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3437        enforceNotIsolatedCaller("startActivityAndWait");
3438        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3439                false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
3440        WaitResult res = new WaitResult();
3441        // TODO: Switch to user app stacks here.
3442        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3443                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
3444                options, userId, null, null);
3445        return res;
3446    }
3447
3448    @Override
3449    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3450            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3451            int startFlags, Configuration config, Bundle options, int userId) {
3452        enforceNotIsolatedCaller("startActivityWithConfig");
3453        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3454                false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
3455        // TODO: Switch to user app stacks here.
3456        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3457                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3458                null, null, config, options, userId, null, null);
3459        return ret;
3460    }
3461
3462    @Override
3463    public int startActivityIntentSender(IApplicationThread caller,
3464            IntentSender intent, Intent fillInIntent, String resolvedType,
3465            IBinder resultTo, String resultWho, int requestCode,
3466            int flagsMask, int flagsValues, Bundle options) {
3467        enforceNotIsolatedCaller("startActivityIntentSender");
3468        // Refuse possible leaked file descriptors
3469        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3470            throw new IllegalArgumentException("File descriptors passed in Intent");
3471        }
3472
3473        IIntentSender sender = intent.getTarget();
3474        if (!(sender instanceof PendingIntentRecord)) {
3475            throw new IllegalArgumentException("Bad PendingIntent object");
3476        }
3477
3478        PendingIntentRecord pir = (PendingIntentRecord)sender;
3479
3480        synchronized (this) {
3481            // If this is coming from the currently resumed activity, it is
3482            // effectively saying that app switches are allowed at this point.
3483            final ActivityStack stack = getFocusedStack();
3484            if (stack.mResumedActivity != null &&
3485                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3486                mAppSwitchesAllowedTime = 0;
3487            }
3488        }
3489        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3490                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3491        return ret;
3492    }
3493
3494    @Override
3495    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3496            Intent intent, String resolvedType, IVoiceInteractionSession session,
3497            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
3498            Bundle options, int userId) {
3499        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3500                != PackageManager.PERMISSION_GRANTED) {
3501            String msg = "Permission Denial: startVoiceActivity() from pid="
3502                    + Binder.getCallingPid()
3503                    + ", uid=" + Binder.getCallingUid()
3504                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3505            Slog.w(TAG, msg);
3506            throw new SecurityException(msg);
3507        }
3508        if (session == null || interactor == null) {
3509            throw new NullPointerException("null session or interactor");
3510        }
3511        userId = handleIncomingUser(callingPid, callingUid, userId,
3512                false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
3513        // TODO: Switch to user app stacks here.
3514        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3515                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
3516                null, options, userId, null, null);
3517    }
3518
3519    @Override
3520    public boolean startNextMatchingActivity(IBinder callingActivity,
3521            Intent intent, Bundle options) {
3522        // Refuse possible leaked file descriptors
3523        if (intent != null && intent.hasFileDescriptors() == true) {
3524            throw new IllegalArgumentException("File descriptors passed in Intent");
3525        }
3526
3527        synchronized (this) {
3528            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3529            if (r == null) {
3530                ActivityOptions.abort(options);
3531                return false;
3532            }
3533            if (r.app == null || r.app.thread == null) {
3534                // The caller is not running...  d'oh!
3535                ActivityOptions.abort(options);
3536                return false;
3537            }
3538            intent = new Intent(intent);
3539            // The caller is not allowed to change the data.
3540            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3541            // And we are resetting to find the next component...
3542            intent.setComponent(null);
3543
3544            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3545
3546            ActivityInfo aInfo = null;
3547            try {
3548                List<ResolveInfo> resolves =
3549                    AppGlobals.getPackageManager().queryIntentActivities(
3550                            intent, r.resolvedType,
3551                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3552                            UserHandle.getCallingUserId());
3553
3554                // Look for the original activity in the list...
3555                final int N = resolves != null ? resolves.size() : 0;
3556                for (int i=0; i<N; i++) {
3557                    ResolveInfo rInfo = resolves.get(i);
3558                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3559                            && rInfo.activityInfo.name.equals(r.info.name)) {
3560                        // We found the current one...  the next matching is
3561                        // after it.
3562                        i++;
3563                        if (i<N) {
3564                            aInfo = resolves.get(i).activityInfo;
3565                        }
3566                        if (debug) {
3567                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3568                                    + "/" + r.info.name);
3569                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3570                                    + "/" + aInfo.name);
3571                        }
3572                        break;
3573                    }
3574                }
3575            } catch (RemoteException e) {
3576            }
3577
3578            if (aInfo == null) {
3579                // Nobody who is next!
3580                ActivityOptions.abort(options);
3581                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3582                return false;
3583            }
3584
3585            intent.setComponent(new ComponentName(
3586                    aInfo.applicationInfo.packageName, aInfo.name));
3587            intent.setFlags(intent.getFlags()&~(
3588                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3589                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3590                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3591                    Intent.FLAG_ACTIVITY_NEW_TASK));
3592
3593            // Okay now we need to start the new activity, replacing the
3594            // currently running activity.  This is a little tricky because
3595            // we want to start the new one as if the current one is finished,
3596            // but not finish the current one first so that there is no flicker.
3597            // And thus...
3598            final boolean wasFinishing = r.finishing;
3599            r.finishing = true;
3600
3601            // Propagate reply information over to the new activity.
3602            final ActivityRecord resultTo = r.resultTo;
3603            final String resultWho = r.resultWho;
3604            final int requestCode = r.requestCode;
3605            r.resultTo = null;
3606            if (resultTo != null) {
3607                resultTo.removeResultsLocked(r, resultWho, requestCode);
3608            }
3609
3610            final long origId = Binder.clearCallingIdentity();
3611            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3612                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3613                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage,
3614                    -1, r.launchedFromUid, 0, options, false, null, null, null);
3615            Binder.restoreCallingIdentity(origId);
3616
3617            r.finishing = wasFinishing;
3618            if (res != ActivityManager.START_SUCCESS) {
3619                return false;
3620            }
3621            return true;
3622        }
3623    }
3624
3625    @Override
3626    public final int startActivityFromRecents(int taskId, Bundle options) {
3627        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
3628            String msg = "Permission Denial: startActivityFromRecents called without " +
3629                    START_TASKS_FROM_RECENTS;
3630            Slog.w(TAG, msg);
3631            throw new SecurityException(msg);
3632        }
3633        return startActivityFromRecentsInner(taskId, options);
3634    }
3635
3636    final int startActivityFromRecentsInner(int taskId, Bundle options) {
3637        final TaskRecord task;
3638        final int callingUid;
3639        final String callingPackage;
3640        final Intent intent;
3641        final int userId;
3642        synchronized (this) {
3643            task = recentTaskForIdLocked(taskId);
3644            if (task == null) {
3645                throw new IllegalArgumentException("Task " + taskId + " not found.");
3646            }
3647            if (task.getRootActivity() != null) {
3648                moveTaskToFrontLocked(task.taskId, 0, null);
3649                return ActivityManager.START_TASK_TO_FRONT;
3650            }
3651            callingUid = task.mCallingUid;
3652            callingPackage = task.mCallingPackage;
3653            intent = task.intent;
3654            intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
3655            userId = task.userId;
3656        }
3657        return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
3658                options, userId, null, task);
3659    }
3660
3661    final int startActivityInPackage(int uid, String callingPackage,
3662            Intent intent, String resolvedType, IBinder resultTo,
3663            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3664            IActivityContainer container, TaskRecord inTask) {
3665
3666        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3667                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3668
3669        // TODO: Switch to user app stacks here.
3670        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent,
3671                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3672                null, null, null, options, userId, container, inTask);
3673        return ret;
3674    }
3675
3676    @Override
3677    public final int startActivities(IApplicationThread caller, String callingPackage,
3678            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3679            int userId) {
3680        enforceNotIsolatedCaller("startActivities");
3681        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3682                false, ALLOW_FULL_ONLY, "startActivity", null);
3683        // TODO: Switch to user app stacks here.
3684        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3685                resolvedTypes, resultTo, options, userId);
3686        return ret;
3687    }
3688
3689    final int startActivitiesInPackage(int uid, String callingPackage,
3690            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3691            Bundle options, int userId) {
3692
3693        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3694                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3695        // TODO: Switch to user app stacks here.
3696        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3697                resultTo, options, userId);
3698        return ret;
3699    }
3700
3701    //explicitly remove thd old information in mRecentTasks when removing existing user.
3702    private void removeRecentTasksForUserLocked(int userId) {
3703        if(userId <= 0) {
3704            Slog.i(TAG, "Can't remove recent task on user " + userId);
3705            return;
3706        }
3707
3708        for (int i = mRecentTasks.size() - 1; i >= 0; --i) {
3709            TaskRecord tr = mRecentTasks.get(i);
3710            if (tr.userId == userId) {
3711                if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr
3712                        + " when finishing user" + userId);
3713                mRecentTasks.remove(i);
3714                tr.removedFromRecents();
3715            }
3716        }
3717
3718        // Remove tasks from persistent storage.
3719        notifyTaskPersisterLocked(null, true);
3720    }
3721
3722    // Sort by taskId
3723    private Comparator<TaskRecord> mTaskRecordComparator = new Comparator<TaskRecord>() {
3724        @Override
3725        public int compare(TaskRecord lhs, TaskRecord rhs) {
3726            return rhs.taskId - lhs.taskId;
3727        }
3728    };
3729
3730    // Extract the affiliates of the chain containing mRecentTasks[start].
3731    private int processNextAffiliateChainLocked(int start) {
3732        final TaskRecord startTask = mRecentTasks.get(start);
3733        final int affiliateId = startTask.mAffiliatedTaskId;
3734
3735        // Quick identification of isolated tasks. I.e. those not launched behind.
3736        if (startTask.taskId == affiliateId && startTask.mPrevAffiliate == null &&
3737                startTask.mNextAffiliate == null) {
3738            // There is still a slim chance that there are other tasks that point to this task
3739            // and that the chain is so messed up that this task no longer points to them but
3740            // the gain of this optimization outweighs the risk.
3741            startTask.inRecents = true;
3742            return start + 1;
3743        }
3744
3745        // Remove all tasks that are affiliated to affiliateId and put them in mTmpRecents.
3746        mTmpRecents.clear();
3747        for (int i = mRecentTasks.size() - 1; i >= start; --i) {
3748            final TaskRecord task = mRecentTasks.get(i);
3749            if (task.mAffiliatedTaskId == affiliateId) {
3750                mRecentTasks.remove(i);
3751                mTmpRecents.add(task);
3752            }
3753        }
3754
3755        // Sort them all by taskId. That is the order they were create in and that order will
3756        // always be correct.
3757        Collections.sort(mTmpRecents, mTaskRecordComparator);
3758
3759        // Go through and fix up the linked list.
3760        // The first one is the end of the chain and has no next.
3761        final TaskRecord first = mTmpRecents.get(0);
3762        first.inRecents = true;
3763        if (first.mNextAffiliate != null) {
3764            Slog.w(TAG, "Link error 1 first.next=" + first.mNextAffiliate);
3765            first.setNextAffiliate(null);
3766            notifyTaskPersisterLocked(first, false);
3767        }
3768        // Everything in the middle is doubly linked from next to prev.
3769        final int tmpSize = mTmpRecents.size();
3770        for (int i = 0; i < tmpSize - 1; ++i) {
3771            final TaskRecord next = mTmpRecents.get(i);
3772            final TaskRecord prev = mTmpRecents.get(i + 1);
3773            if (next.mPrevAffiliate != prev) {
3774                Slog.w(TAG, "Link error 2 next=" + next + " prev=" + next.mPrevAffiliate +
3775                        " setting prev=" + prev);
3776                next.setPrevAffiliate(prev);
3777                notifyTaskPersisterLocked(next, false);
3778            }
3779            if (prev.mNextAffiliate != next) {
3780                Slog.w(TAG, "Link error 3 prev=" + prev + " next=" + prev.mNextAffiliate +
3781                        " setting next=" + next);
3782                prev.setNextAffiliate(next);
3783                notifyTaskPersisterLocked(prev, false);
3784            }
3785            prev.inRecents = true;
3786        }
3787        // The last one is the beginning of the list and has no prev.
3788        final TaskRecord last = mTmpRecents.get(tmpSize - 1);
3789        if (last.mPrevAffiliate != null) {
3790            Slog.w(TAG, "Link error 4 last.prev=" + last.mPrevAffiliate);
3791            last.setPrevAffiliate(null);
3792            notifyTaskPersisterLocked(last, false);
3793        }
3794
3795        // Insert the group back into mRecentTasks at start.
3796        mRecentTasks.addAll(start, mTmpRecents);
3797
3798        // Let the caller know where we left off.
3799        return start + tmpSize;
3800    }
3801
3802    /**
3803     * Update the recent tasks lists: make sure tasks should still be here (their
3804     * applications / activities still exist), update their availability, fixup ordering
3805     * of affiliations.
3806     */
3807    void cleanupRecentTasksLocked(int userId) {
3808        if (mRecentTasks == null) {
3809            // Happens when called from the packagemanager broadcast before boot.
3810            return;
3811        }
3812
3813        final HashMap<ComponentName, ActivityInfo> availActCache = new HashMap<>();
3814        final HashMap<String, ApplicationInfo> availAppCache = new HashMap<>();
3815        final IPackageManager pm = AppGlobals.getPackageManager();
3816        final ActivityInfo dummyAct = new ActivityInfo();
3817        final ApplicationInfo dummyApp = new ApplicationInfo();
3818
3819        int N = mRecentTasks.size();
3820
3821        int[] users = userId == UserHandle.USER_ALL
3822                ? getUsersLocked() : new int[] { userId };
3823        for (int user : users) {
3824            for (int i = 0; i < N; i++) {
3825                TaskRecord task = mRecentTasks.get(i);
3826                if (task.userId != user) {
3827                    // Only look at tasks for the user ID of interest.
3828                    continue;
3829                }
3830                if (task.autoRemoveRecents && task.getTopActivity() == null) {
3831                    // This situation is broken, and we should just get rid of it now.
3832                    mRecentTasks.remove(i);
3833                    task.removedFromRecents();
3834                    i--;
3835                    N--;
3836                    Slog.w(TAG, "Removing auto-remove without activity: " + task);
3837                    continue;
3838                }
3839                // Check whether this activity is currently available.
3840                if (task.realActivity != null) {
3841                    ActivityInfo ai = availActCache.get(task.realActivity);
3842                    if (ai == null) {
3843                        try {
3844                            ai = pm.getActivityInfo(task.realActivity,
3845                                    PackageManager.GET_UNINSTALLED_PACKAGES
3846                                    | PackageManager.GET_DISABLED_COMPONENTS, user);
3847                        } catch (RemoteException e) {
3848                            // Will never happen.
3849                            continue;
3850                        }
3851                        if (ai == null) {
3852                            ai = dummyAct;
3853                        }
3854                        availActCache.put(task.realActivity, ai);
3855                    }
3856                    if (ai == dummyAct) {
3857                        // This could be either because the activity no longer exists, or the
3858                        // app is temporarily gone.  For the former we want to remove the recents
3859                        // entry; for the latter we want to mark it as unavailable.
3860                        ApplicationInfo app = availAppCache.get(task.realActivity.getPackageName());
3861                        if (app == null) {
3862                            try {
3863                                app = pm.getApplicationInfo(task.realActivity.getPackageName(),
3864                                        PackageManager.GET_UNINSTALLED_PACKAGES
3865                                        | PackageManager.GET_DISABLED_COMPONENTS, user);
3866                            } catch (RemoteException e) {
3867                                // Will never happen.
3868                                continue;
3869                            }
3870                            if (app == null) {
3871                                app = dummyApp;
3872                            }
3873                            availAppCache.put(task.realActivity.getPackageName(), app);
3874                        }
3875                        if (app == dummyApp || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
3876                            // Doesn't exist any more!  Good-bye.
3877                            mRecentTasks.remove(i);
3878                            task.removedFromRecents();
3879                            i--;
3880                            N--;
3881                            Slog.w(TAG, "Removing no longer valid recent: " + task);
3882                            continue;
3883                        } else {
3884                            // Otherwise just not available for now.
3885                            if (task.isAvailable) {
3886                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
3887                                        + task);
3888                            }
3889                            task.isAvailable = false;
3890                        }
3891                    } else {
3892                        if (!ai.enabled || !ai.applicationInfo.enabled
3893                                || (ai.applicationInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
3894                            if (task.isAvailable) {
3895                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
3896                                        + task + " (enabled=" + ai.enabled + "/"
3897                                        + ai.applicationInfo.enabled +  " flags="
3898                                        + Integer.toHexString(ai.applicationInfo.flags) + ")");
3899                            }
3900                            task.isAvailable = false;
3901                        } else {
3902                            if (!task.isAvailable) {
3903                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent available: "
3904                                        + task);
3905                            }
3906                            task.isAvailable = true;
3907                        }
3908                    }
3909                }
3910            }
3911        }
3912
3913        // Verify the affiliate chain for each task.
3914        for (int i = 0; i < N; i = processNextAffiliateChainLocked(i)) {
3915        }
3916
3917        mTmpRecents.clear();
3918        // mRecentTasks is now in sorted, affiliated order.
3919    }
3920
3921    private final boolean moveAffiliatedTasksToFront(TaskRecord task, int taskIndex) {
3922        int N = mRecentTasks.size();
3923        TaskRecord top = task;
3924        int topIndex = taskIndex;
3925        while (top.mNextAffiliate != null && topIndex > 0) {
3926            top = top.mNextAffiliate;
3927            topIndex--;
3928        }
3929        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding affilliates starting at "
3930                + topIndex + " from intial " + taskIndex);
3931        // Find the end of the chain, doing a sanity check along the way.
3932        boolean sane = top.mAffiliatedTaskId == task.mAffiliatedTaskId;
3933        int endIndex = topIndex;
3934        TaskRecord prev = top;
3935        while (endIndex < N) {
3936            TaskRecord cur = mRecentTasks.get(endIndex);
3937            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: looking at next chain @"
3938                    + endIndex + " " + cur);
3939            if (cur == top) {
3940                // Verify start of the chain.
3941                if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != INVALID_TASK_ID) {
3942                    Slog.wtf(TAG, "Bad chain @" + endIndex
3943                            + ": first task has next affiliate: " + prev);
3944                    sane = false;
3945                    break;
3946                }
3947            } else {
3948                // Verify middle of the chain's next points back to the one before.
3949                if (cur.mNextAffiliate != prev
3950                        || cur.mNextAffiliateTaskId != prev.taskId) {
3951                    Slog.wtf(TAG, "Bad chain @" + endIndex
3952                            + ": middle task " + cur + " @" + endIndex
3953                            + " has bad next affiliate "
3954                            + cur.mNextAffiliate + " id " + cur.mNextAffiliateTaskId
3955                            + ", expected " + prev);
3956                    sane = false;
3957                    break;
3958                }
3959            }
3960            if (cur.mPrevAffiliateTaskId == INVALID_TASK_ID) {
3961                // Chain ends here.
3962                if (cur.mPrevAffiliate != null) {
3963                    Slog.wtf(TAG, "Bad chain @" + endIndex
3964                            + ": last task " + cur + " has previous affiliate "
3965                            + cur.mPrevAffiliate);
3966                    sane = false;
3967                }
3968                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: end of chain @" + endIndex);
3969                break;
3970            } else {
3971                // Verify middle of the chain's prev points to a valid item.
3972                if (cur.mPrevAffiliate == null) {
3973                    Slog.wtf(TAG, "Bad chain @" + endIndex
3974                            + ": task " + cur + " has previous affiliate "
3975                            + cur.mPrevAffiliate + " but should be id "
3976                            + cur.mPrevAffiliate);
3977                    sane = false;
3978                    break;
3979                }
3980            }
3981            if (cur.mAffiliatedTaskId != task.mAffiliatedTaskId) {
3982                Slog.wtf(TAG, "Bad chain @" + endIndex
3983                        + ": task " + cur + " has affiliated id "
3984                        + cur.mAffiliatedTaskId + " but should be "
3985                        + task.mAffiliatedTaskId);
3986                sane = false;
3987                break;
3988            }
3989            prev = cur;
3990            endIndex++;
3991            if (endIndex >= N) {
3992                Slog.wtf(TAG, "Bad chain ran off index " + endIndex
3993                        + ": last task " + prev);
3994                sane = false;
3995                break;
3996            }
3997        }
3998        if (sane) {
3999            if (endIndex < taskIndex) {
4000                Slog.wtf(TAG, "Bad chain @" + endIndex
4001                        + ": did not extend to task " + task + " @" + taskIndex);
4002                sane = false;
4003            }
4004        }
4005        if (sane) {
4006            // All looks good, we can just move all of the affiliated tasks
4007            // to the top.
4008            for (int i=topIndex; i<=endIndex; i++) {
4009                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving affiliated " + task
4010                        + " from " + i + " to " + (i-topIndex));
4011                TaskRecord cur = mRecentTasks.remove(i);
4012                mRecentTasks.add(i-topIndex, cur);
4013            }
4014            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: done moving tasks  " +  topIndex
4015                    + " to " + endIndex);
4016            return true;
4017        }
4018
4019        // Whoops, couldn't do it.
4020        return false;
4021    }
4022
4023    final void addRecentTaskLocked(TaskRecord task) {
4024        final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId
4025                || task.mNextAffiliateTaskId != INVALID_TASK_ID
4026                || task.mPrevAffiliateTaskId != INVALID_TASK_ID;
4027
4028        int N = mRecentTasks.size();
4029        // Quick case: check if the top-most recent task is the same.
4030        if (!isAffiliated && N > 0 && mRecentTasks.get(0) == task) {
4031            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: already at top: " + task);
4032            return;
4033        }
4034        // Another quick case: check if this is part of a set of affiliated
4035        // tasks that are at the top.
4036        if (isAffiliated && N > 0 && task.inRecents
4037                && task.mAffiliatedTaskId == mRecentTasks.get(0).mAffiliatedTaskId) {
4038            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: affiliated " + mRecentTasks.get(0)
4039                    + " at top when adding " + task);
4040            return;
4041        }
4042        // Another quick case: never add voice sessions.
4043        if (task.voiceSession != null) {
4044            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: not adding voice interaction " + task);
4045            return;
4046        }
4047
4048        boolean needAffiliationFix = false;
4049
4050        // Slightly less quick case: the task is already in recents, so all we need
4051        // to do is move it.
4052        if (task.inRecents) {
4053            int taskIndex = mRecentTasks.indexOf(task);
4054            if (taskIndex >= 0) {
4055                if (!isAffiliated) {
4056                    // Simple case: this is not an affiliated task, so we just move it to the front.
4057                    mRecentTasks.remove(taskIndex);
4058                    mRecentTasks.add(0, task);
4059                    notifyTaskPersisterLocked(task, false);
4060                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving to top " + task
4061                            + " from " + taskIndex);
4062                    return;
4063                } else {
4064                    // More complicated: need to keep all affiliated tasks together.
4065                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
4066                        // All went well.
4067                        return;
4068                    }
4069
4070                    // Uh oh...  something bad in the affiliation chain, try to rebuild
4071                    // everything and then go through our general path of adding a new task.
4072                    needAffiliationFix = true;
4073                }
4074            } else {
4075                Slog.wtf(TAG, "Task with inRecent not in recents: " + task);
4076                needAffiliationFix = true;
4077            }
4078        }
4079
4080        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: trimming tasks for " + task);
4081        trimRecentsForTaskLocked(task, true);
4082
4083        N = mRecentTasks.size();
4084        while (N >= ActivityManager.getMaxRecentTasksStatic()) {
4085            final TaskRecord tr = mRecentTasks.remove(N - 1);
4086            tr.removedFromRecents();
4087            N--;
4088        }
4089        task.inRecents = true;
4090        if (!isAffiliated || needAffiliationFix) {
4091            // If this is a simple non-affiliated task, or we had some failure trying to
4092            // handle it as part of an affilated task, then just place it at the top.
4093            mRecentTasks.add(0, task);
4094        } else if (isAffiliated) {
4095            // If this is a new affiliated task, then move all of the affiliated tasks
4096            // to the front and insert this new one.
4097            TaskRecord other = task.mNextAffiliate;
4098            if (other == null) {
4099                other = task.mPrevAffiliate;
4100            }
4101            if (other != null) {
4102                int otherIndex = mRecentTasks.indexOf(other);
4103                if (otherIndex >= 0) {
4104                    // Insert new task at appropriate location.
4105                    int taskIndex;
4106                    if (other == task.mNextAffiliate) {
4107                        // We found the index of our next affiliation, which is who is
4108                        // before us in the list, so add after that point.
4109                        taskIndex = otherIndex+1;
4110                    } else {
4111                        // We found the index of our previous affiliation, which is who is
4112                        // after us in the list, so add at their position.
4113                        taskIndex = otherIndex;
4114                    }
4115                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: new affiliated task added at "
4116                            + taskIndex + ": " + task);
4117                    mRecentTasks.add(taskIndex, task);
4118
4119                    // Now move everything to the front.
4120                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
4121                        // All went well.
4122                        return;
4123                    }
4124
4125                    // Uh oh...  something bad in the affiliation chain, try to rebuild
4126                    // everything and then go through our general path of adding a new task.
4127                    needAffiliationFix = true;
4128                } else {
4129                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: couldn't find other affiliation "
4130                            + other);
4131                    needAffiliationFix = true;
4132                }
4133            } else {
4134                if (DEBUG_RECENTS) Slog.d(TAG,
4135                        "addRecent: adding affiliated task without next/prev:" + task);
4136                needAffiliationFix = true;
4137            }
4138        }
4139        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding " + task);
4140
4141        if (needAffiliationFix) {
4142            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: regrouping affiliations");
4143            cleanupRecentTasksLocked(task.userId);
4144        }
4145    }
4146
4147    /**
4148     * If needed, remove oldest existing entries in recents that are for the same kind
4149     * of task as the given one.
4150     */
4151    int trimRecentsForTaskLocked(TaskRecord task, boolean doTrim) {
4152        int N = mRecentTasks.size();
4153        final Intent intent = task.intent;
4154        final boolean document = intent != null && intent.isDocument();
4155
4156        int maxRecents = task.maxRecents - 1;
4157        for (int i=0; i<N; i++) {
4158            final TaskRecord tr = mRecentTasks.get(i);
4159            if (task != tr) {
4160                if (task.userId != tr.userId) {
4161                    continue;
4162                }
4163                if (i > MAX_RECENT_BITMAPS) {
4164                    tr.freeLastThumbnail();
4165                }
4166                final Intent trIntent = tr.intent;
4167                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
4168                    (intent == null || !intent.filterEquals(trIntent))) {
4169                    continue;
4170                }
4171                final boolean trIsDocument = trIntent != null && trIntent.isDocument();
4172                if (document && trIsDocument) {
4173                    // These are the same document activity (not necessarily the same doc).
4174                    if (maxRecents > 0) {
4175                        --maxRecents;
4176                        continue;
4177                    }
4178                    // Hit the maximum number of documents for this task. Fall through
4179                    // and remove this document from recents.
4180                } else if (document || trIsDocument) {
4181                    // Only one of these is a document. Not the droid we're looking for.
4182                    continue;
4183                }
4184            }
4185
4186            if (!doTrim) {
4187                // If the caller is not actually asking for a trim, just tell them we reached
4188                // a point where the trim would happen.
4189                return i;
4190            }
4191
4192            // Either task and tr are the same or, their affinities match or their intents match
4193            // and neither of them is a document, or they are documents using the same activity
4194            // and their maxRecents has been reached.
4195            tr.disposeThumbnail();
4196            mRecentTasks.remove(i);
4197            if (task != tr) {
4198                tr.removedFromRecents();
4199            }
4200            i--;
4201            N--;
4202            if (task.intent == null) {
4203                // If the new recent task we are adding is not fully
4204                // specified, then replace it with the existing recent task.
4205                task = tr;
4206            }
4207            notifyTaskPersisterLocked(tr, false);
4208        }
4209
4210        return -1;
4211    }
4212
4213    @Override
4214    public void reportActivityFullyDrawn(IBinder token) {
4215        synchronized (this) {
4216            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4217            if (r == null) {
4218                return;
4219            }
4220            r.reportFullyDrawnLocked();
4221        }
4222    }
4223
4224    @Override
4225    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4226        synchronized (this) {
4227            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4228            if (r == null) {
4229                return;
4230            }
4231            final long origId = Binder.clearCallingIdentity();
4232            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4233            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4234                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4235            if (config != null) {
4236                r.frozenBeforeDestroy = true;
4237                if (!updateConfigurationLocked(config, r, false, false)) {
4238                    mStackSupervisor.resumeTopActivitiesLocked();
4239                }
4240            }
4241            Binder.restoreCallingIdentity(origId);
4242        }
4243    }
4244
4245    @Override
4246    public int getRequestedOrientation(IBinder token) {
4247        synchronized (this) {
4248            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4249            if (r == null) {
4250                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4251            }
4252            return mWindowManager.getAppOrientation(r.appToken);
4253        }
4254    }
4255
4256    /**
4257     * This is the internal entry point for handling Activity.finish().
4258     *
4259     * @param token The Binder token referencing the Activity we want to finish.
4260     * @param resultCode Result code, if any, from this Activity.
4261     * @param resultData Result data (Intent), if any, from this Activity.
4262     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
4263     *            the root Activity in the task.
4264     *
4265     * @return Returns true if the activity successfully finished, or false if it is still running.
4266     */
4267    @Override
4268    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4269            boolean finishTask) {
4270        // Refuse possible leaked file descriptors
4271        if (resultData != null && resultData.hasFileDescriptors() == true) {
4272            throw new IllegalArgumentException("File descriptors passed in Intent");
4273        }
4274
4275        synchronized(this) {
4276            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4277            if (r == null) {
4278                return true;
4279            }
4280            // Keep track of the root activity of the task before we finish it
4281            TaskRecord tr = r.task;
4282            ActivityRecord rootR = tr.getRootActivity();
4283            if (rootR == null) {
4284                Slog.w(TAG, "Finishing task with all activities already finished");
4285            }
4286            // Do not allow task to finish in Lock Task mode.
4287            if (tr == mStackSupervisor.mLockTaskModeTask) {
4288                if (rootR == r) {
4289                    Slog.i(TAG, "Not finishing task in lock task mode");
4290                    mStackSupervisor.showLockTaskToast();
4291                    return false;
4292                }
4293            }
4294            if (mController != null) {
4295                // Find the first activity that is not finishing.
4296                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4297                if (next != null) {
4298                    // ask watcher if this is allowed
4299                    boolean resumeOK = true;
4300                    try {
4301                        resumeOK = mController.activityResuming(next.packageName);
4302                    } catch (RemoteException e) {
4303                        mController = null;
4304                        Watchdog.getInstance().setActivityController(null);
4305                    }
4306
4307                    if (!resumeOK) {
4308                        Slog.i(TAG, "Not finishing activity because controller resumed");
4309                        return false;
4310                    }
4311                }
4312            }
4313            final long origId = Binder.clearCallingIdentity();
4314            try {
4315                boolean res;
4316                if (finishTask && r == rootR) {
4317                    // If requested, remove the task that is associated to this activity only if it
4318                    // was the root activity in the task. The result code and data is ignored
4319                    // because we don't support returning them across task boundaries.
4320                    res = removeTaskByIdLocked(tr.taskId, false);
4321                    if (!res) {
4322                        Slog.i(TAG, "Removing task failed to finish activity");
4323                    }
4324                } else {
4325                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4326                            resultData, "app-request", true);
4327                    if (!res) {
4328                        Slog.i(TAG, "Failed to finish by app-request");
4329                    }
4330                }
4331                return res;
4332            } finally {
4333                Binder.restoreCallingIdentity(origId);
4334            }
4335        }
4336    }
4337
4338    @Override
4339    public final void finishHeavyWeightApp() {
4340        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4341                != PackageManager.PERMISSION_GRANTED) {
4342            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4343                    + Binder.getCallingPid()
4344                    + ", uid=" + Binder.getCallingUid()
4345                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4346            Slog.w(TAG, msg);
4347            throw new SecurityException(msg);
4348        }
4349
4350        synchronized(this) {
4351            if (mHeavyWeightProcess == null) {
4352                return;
4353            }
4354
4355            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
4356                    mHeavyWeightProcess.activities);
4357            for (int i=0; i<activities.size(); i++) {
4358                ActivityRecord r = activities.get(i);
4359                if (!r.finishing) {
4360                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4361                            null, "finish-heavy", true);
4362                }
4363            }
4364
4365            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4366                    mHeavyWeightProcess.userId, 0));
4367            mHeavyWeightProcess = null;
4368        }
4369    }
4370
4371    @Override
4372    public void crashApplication(int uid, int initialPid, String packageName,
4373            String message) {
4374        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4375                != PackageManager.PERMISSION_GRANTED) {
4376            String msg = "Permission Denial: crashApplication() from pid="
4377                    + Binder.getCallingPid()
4378                    + ", uid=" + Binder.getCallingUid()
4379                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4380            Slog.w(TAG, msg);
4381            throw new SecurityException(msg);
4382        }
4383
4384        synchronized(this) {
4385            ProcessRecord proc = null;
4386
4387            // Figure out which process to kill.  We don't trust that initialPid
4388            // still has any relation to current pids, so must scan through the
4389            // list.
4390            synchronized (mPidsSelfLocked) {
4391                for (int i=0; i<mPidsSelfLocked.size(); i++) {
4392                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
4393                    if (p.uid != uid) {
4394                        continue;
4395                    }
4396                    if (p.pid == initialPid) {
4397                        proc = p;
4398                        break;
4399                    }
4400                    if (p.pkgList.containsKey(packageName)) {
4401                        proc = p;
4402                    }
4403                }
4404            }
4405
4406            if (proc == null) {
4407                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
4408                        + " initialPid=" + initialPid
4409                        + " packageName=" + packageName);
4410                return;
4411            }
4412
4413            if (proc.thread != null) {
4414                if (proc.pid == Process.myPid()) {
4415                    Log.w(TAG, "crashApplication: trying to crash self!");
4416                    return;
4417                }
4418                long ident = Binder.clearCallingIdentity();
4419                try {
4420                    proc.thread.scheduleCrash(message);
4421                } catch (RemoteException e) {
4422                }
4423                Binder.restoreCallingIdentity(ident);
4424            }
4425        }
4426    }
4427
4428    @Override
4429    public final void finishSubActivity(IBinder token, String resultWho,
4430            int requestCode) {
4431        synchronized(this) {
4432            final long origId = Binder.clearCallingIdentity();
4433            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4434            if (r != null) {
4435                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4436            }
4437            Binder.restoreCallingIdentity(origId);
4438        }
4439    }
4440
4441    @Override
4442    public boolean finishActivityAffinity(IBinder token) {
4443        synchronized(this) {
4444            final long origId = Binder.clearCallingIdentity();
4445            try {
4446                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4447
4448                ActivityRecord rootR = r.task.getRootActivity();
4449                // Do not allow task to finish in Lock Task mode.
4450                if (r.task == mStackSupervisor.mLockTaskModeTask) {
4451                    if (rootR == r) {
4452                        mStackSupervisor.showLockTaskToast();
4453                        return false;
4454                    }
4455                }
4456                boolean res = false;
4457                if (r != null) {
4458                    res = r.task.stack.finishActivityAffinityLocked(r);
4459                }
4460                return res;
4461            } finally {
4462                Binder.restoreCallingIdentity(origId);
4463            }
4464        }
4465    }
4466
4467    @Override
4468    public void finishVoiceTask(IVoiceInteractionSession session) {
4469        synchronized(this) {
4470            final long origId = Binder.clearCallingIdentity();
4471            try {
4472                mStackSupervisor.finishVoiceTask(session);
4473            } finally {
4474                Binder.restoreCallingIdentity(origId);
4475            }
4476        }
4477
4478    }
4479
4480    @Override
4481    public boolean releaseActivityInstance(IBinder token) {
4482        synchronized(this) {
4483            final long origId = Binder.clearCallingIdentity();
4484            try {
4485                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4486                if (r.task == null || r.task.stack == null) {
4487                    return false;
4488                }
4489                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4490            } finally {
4491                Binder.restoreCallingIdentity(origId);
4492            }
4493        }
4494    }
4495
4496    @Override
4497    public void releaseSomeActivities(IApplicationThread appInt) {
4498        synchronized(this) {
4499            final long origId = Binder.clearCallingIdentity();
4500            try {
4501                ProcessRecord app = getRecordForAppLocked(appInt);
4502                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4503            } finally {
4504                Binder.restoreCallingIdentity(origId);
4505            }
4506        }
4507    }
4508
4509    @Override
4510    public boolean willActivityBeVisible(IBinder token) {
4511        synchronized(this) {
4512            ActivityStack stack = ActivityRecord.getStackLocked(token);
4513            if (stack != null) {
4514                return stack.willActivityBeVisibleLocked(token);
4515            }
4516            return false;
4517        }
4518    }
4519
4520    @Override
4521    public void overridePendingTransition(IBinder token, String packageName,
4522            int enterAnim, int exitAnim) {
4523        synchronized(this) {
4524            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4525            if (self == null) {
4526                return;
4527            }
4528
4529            final long origId = Binder.clearCallingIdentity();
4530
4531            if (self.state == ActivityState.RESUMED
4532                    || self.state == ActivityState.PAUSING) {
4533                mWindowManager.overridePendingAppTransition(packageName,
4534                        enterAnim, exitAnim, null);
4535            }
4536
4537            Binder.restoreCallingIdentity(origId);
4538        }
4539    }
4540
4541    /**
4542     * Main function for removing an existing process from the activity manager
4543     * as a result of that process going away.  Clears out all connections
4544     * to the process.
4545     */
4546    private final void handleAppDiedLocked(ProcessRecord app,
4547            boolean restarting, boolean allowRestart) {
4548        int pid = app.pid;
4549        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4550        if (!kept && !restarting) {
4551            removeLruProcessLocked(app);
4552            if (pid > 0) {
4553                ProcessList.remove(pid);
4554            }
4555        }
4556
4557        if (mProfileProc == app) {
4558            clearProfilerLocked();
4559        }
4560
4561        // Remove this application's activities from active lists.
4562        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4563
4564        app.activities.clear();
4565
4566        if (app.instrumentationClass != null) {
4567            Slog.w(TAG, "Crash of app " + app.processName
4568                  + " running instrumentation " + app.instrumentationClass);
4569            Bundle info = new Bundle();
4570            info.putString("shortMsg", "Process crashed.");
4571            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4572        }
4573
4574        if (!restarting) {
4575            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
4576                // If there was nothing to resume, and we are not already
4577                // restarting this process, but there is a visible activity that
4578                // is hosted by the process...  then make sure all visible
4579                // activities are running, taking care of restarting this
4580                // process.
4581                if (hasVisibleActivities) {
4582                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
4583                }
4584            }
4585        }
4586    }
4587
4588    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4589        IBinder threadBinder = thread.asBinder();
4590        // Find the application record.
4591        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4592            ProcessRecord rec = mLruProcesses.get(i);
4593            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4594                return i;
4595            }
4596        }
4597        return -1;
4598    }
4599
4600    final ProcessRecord getRecordForAppLocked(
4601            IApplicationThread thread) {
4602        if (thread == null) {
4603            return null;
4604        }
4605
4606        int appIndex = getLRURecordIndexForAppLocked(thread);
4607        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4608    }
4609
4610    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4611        // If there are no longer any background processes running,
4612        // and the app that died was not running instrumentation,
4613        // then tell everyone we are now low on memory.
4614        boolean haveBg = false;
4615        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4616            ProcessRecord rec = mLruProcesses.get(i);
4617            if (rec.thread != null
4618                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4619                haveBg = true;
4620                break;
4621            }
4622        }
4623
4624        if (!haveBg) {
4625            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4626            if (doReport) {
4627                long now = SystemClock.uptimeMillis();
4628                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4629                    doReport = false;
4630                } else {
4631                    mLastMemUsageReportTime = now;
4632                }
4633            }
4634            final ArrayList<ProcessMemInfo> memInfos
4635                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4636            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4637            long now = SystemClock.uptimeMillis();
4638            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4639                ProcessRecord rec = mLruProcesses.get(i);
4640                if (rec == dyingProc || rec.thread == null) {
4641                    continue;
4642                }
4643                if (doReport) {
4644                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4645                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4646                }
4647                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4648                    // The low memory report is overriding any current
4649                    // state for a GC request.  Make sure to do
4650                    // heavy/important/visible/foreground processes first.
4651                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4652                        rec.lastRequestedGc = 0;
4653                    } else {
4654                        rec.lastRequestedGc = rec.lastLowMemory;
4655                    }
4656                    rec.reportLowMemory = true;
4657                    rec.lastLowMemory = now;
4658                    mProcessesToGc.remove(rec);
4659                    addProcessToGcListLocked(rec);
4660                }
4661            }
4662            if (doReport) {
4663                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4664                mHandler.sendMessage(msg);
4665            }
4666            scheduleAppGcsLocked();
4667        }
4668    }
4669
4670    final void appDiedLocked(ProcessRecord app) {
4671       appDiedLocked(app, app.pid, app.thread);
4672    }
4673
4674    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread) {
4675        // First check if this ProcessRecord is actually active for the pid.
4676        synchronized (mPidsSelfLocked) {
4677            ProcessRecord curProc = mPidsSelfLocked.get(pid);
4678            if (curProc != app) {
4679                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
4680                return;
4681            }
4682        }
4683
4684        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4685        synchronized (stats) {
4686            stats.noteProcessDiedLocked(app.info.uid, pid);
4687        }
4688
4689        if (!app.killed) {
4690            Process.killProcessQuiet(pid);
4691            Process.killProcessGroup(app.info.uid, pid);
4692            app.killed = true;
4693        }
4694
4695        // Clean up already done if the process has been re-started.
4696        if (app.pid == pid && app.thread != null &&
4697                app.thread.asBinder() == thread.asBinder()) {
4698            boolean doLowMem = app.instrumentationClass == null;
4699            boolean doOomAdj = doLowMem;
4700            if (!app.killedByAm) {
4701                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4702                        + ") has died");
4703                mAllowLowerMemLevel = true;
4704            } else {
4705                // Note that we always want to do oom adj to update our state with the
4706                // new number of procs.
4707                mAllowLowerMemLevel = false;
4708                doLowMem = false;
4709            }
4710            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4711            if (DEBUG_CLEANUP) Slog.v(
4712                TAG, "Dying app: " + app + ", pid: " + pid
4713                + ", thread: " + thread.asBinder());
4714            handleAppDiedLocked(app, false, true);
4715
4716            if (doOomAdj) {
4717                updateOomAdjLocked();
4718            }
4719            if (doLowMem) {
4720                doLowMemReportIfNeededLocked(app);
4721            }
4722        } else if (app.pid != pid) {
4723            // A new process has already been started.
4724            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4725                    + ") has died and restarted (pid " + app.pid + ").");
4726            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4727        } else if (DEBUG_PROCESSES) {
4728            Slog.d(TAG, "Received spurious death notification for thread "
4729                    + thread.asBinder());
4730        }
4731    }
4732
4733    /**
4734     * If a stack trace dump file is configured, dump process stack traces.
4735     * @param clearTraces causes the dump file to be erased prior to the new
4736     *    traces being written, if true; when false, the new traces will be
4737     *    appended to any existing file content.
4738     * @param firstPids of dalvik VM processes to dump stack traces for first
4739     * @param lastPids of dalvik VM processes to dump stack traces for last
4740     * @param nativeProcs optional list of native process names to dump stack crawls
4741     * @return file containing stack traces, or null if no dump file is configured
4742     */
4743    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4744            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4745        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4746        if (tracesPath == null || tracesPath.length() == 0) {
4747            return null;
4748        }
4749
4750        File tracesFile = new File(tracesPath);
4751        try {
4752            File tracesDir = tracesFile.getParentFile();
4753            if (!tracesDir.exists()) {
4754                tracesDir.mkdirs();
4755                if (!SELinux.restorecon(tracesDir)) {
4756                    return null;
4757                }
4758            }
4759            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4760
4761            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4762            tracesFile.createNewFile();
4763            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4764        } catch (IOException e) {
4765            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4766            return null;
4767        }
4768
4769        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4770        return tracesFile;
4771    }
4772
4773    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4774            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4775        // Use a FileObserver to detect when traces finish writing.
4776        // The order of traces is considered important to maintain for legibility.
4777        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4778            @Override
4779            public synchronized void onEvent(int event, String path) { notify(); }
4780        };
4781
4782        try {
4783            observer.startWatching();
4784
4785            // First collect all of the stacks of the most important pids.
4786            if (firstPids != null) {
4787                try {
4788                    int num = firstPids.size();
4789                    for (int i = 0; i < num; i++) {
4790                        synchronized (observer) {
4791                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4792                            observer.wait(200);  // Wait for write-close, give up after 200msec
4793                        }
4794                    }
4795                } catch (InterruptedException e) {
4796                    Slog.wtf(TAG, e);
4797                }
4798            }
4799
4800            // Next collect the stacks of the native pids
4801            if (nativeProcs != null) {
4802                int[] pids = Process.getPidsForCommands(nativeProcs);
4803                if (pids != null) {
4804                    for (int pid : pids) {
4805                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4806                    }
4807                }
4808            }
4809
4810            // Lastly, measure CPU usage.
4811            if (processCpuTracker != null) {
4812                processCpuTracker.init();
4813                System.gc();
4814                processCpuTracker.update();
4815                try {
4816                    synchronized (processCpuTracker) {
4817                        processCpuTracker.wait(500); // measure over 1/2 second.
4818                    }
4819                } catch (InterruptedException e) {
4820                }
4821                processCpuTracker.update();
4822
4823                // We'll take the stack crawls of just the top apps using CPU.
4824                final int N = processCpuTracker.countWorkingStats();
4825                int numProcs = 0;
4826                for (int i=0; i<N && numProcs<5; i++) {
4827                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4828                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4829                        numProcs++;
4830                        try {
4831                            synchronized (observer) {
4832                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4833                                observer.wait(200);  // Wait for write-close, give up after 200msec
4834                            }
4835                        } catch (InterruptedException e) {
4836                            Slog.wtf(TAG, e);
4837                        }
4838
4839                    }
4840                }
4841            }
4842        } finally {
4843            observer.stopWatching();
4844        }
4845    }
4846
4847    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4848        if (true || IS_USER_BUILD) {
4849            return;
4850        }
4851        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4852        if (tracesPath == null || tracesPath.length() == 0) {
4853            return;
4854        }
4855
4856        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4857        StrictMode.allowThreadDiskWrites();
4858        try {
4859            final File tracesFile = new File(tracesPath);
4860            final File tracesDir = tracesFile.getParentFile();
4861            final File tracesTmp = new File(tracesDir, "__tmp__");
4862            try {
4863                if (!tracesDir.exists()) {
4864                    tracesDir.mkdirs();
4865                    if (!SELinux.restorecon(tracesDir.getPath())) {
4866                        return;
4867                    }
4868                }
4869                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4870
4871                if (tracesFile.exists()) {
4872                    tracesTmp.delete();
4873                    tracesFile.renameTo(tracesTmp);
4874                }
4875                StringBuilder sb = new StringBuilder();
4876                Time tobj = new Time();
4877                tobj.set(System.currentTimeMillis());
4878                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4879                sb.append(": ");
4880                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4881                sb.append(" since ");
4882                sb.append(msg);
4883                FileOutputStream fos = new FileOutputStream(tracesFile);
4884                fos.write(sb.toString().getBytes());
4885                if (app == null) {
4886                    fos.write("\n*** No application process!".getBytes());
4887                }
4888                fos.close();
4889                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4890            } catch (IOException e) {
4891                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4892                return;
4893            }
4894
4895            if (app != null) {
4896                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4897                firstPids.add(app.pid);
4898                dumpStackTraces(tracesPath, firstPids, null, null, null);
4899            }
4900
4901            File lastTracesFile = null;
4902            File curTracesFile = null;
4903            for (int i=9; i>=0; i--) {
4904                String name = String.format(Locale.US, "slow%02d.txt", i);
4905                curTracesFile = new File(tracesDir, name);
4906                if (curTracesFile.exists()) {
4907                    if (lastTracesFile != null) {
4908                        curTracesFile.renameTo(lastTracesFile);
4909                    } else {
4910                        curTracesFile.delete();
4911                    }
4912                }
4913                lastTracesFile = curTracesFile;
4914            }
4915            tracesFile.renameTo(curTracesFile);
4916            if (tracesTmp.exists()) {
4917                tracesTmp.renameTo(tracesFile);
4918            }
4919        } finally {
4920            StrictMode.setThreadPolicy(oldPolicy);
4921        }
4922    }
4923
4924    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4925            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4926        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4927        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4928
4929        if (mController != null) {
4930            try {
4931                // 0 == continue, -1 = kill process immediately
4932                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4933                if (res < 0 && app.pid != MY_PID) {
4934                    app.kill("anr", true);
4935                }
4936            } catch (RemoteException e) {
4937                mController = null;
4938                Watchdog.getInstance().setActivityController(null);
4939            }
4940        }
4941
4942        long anrTime = SystemClock.uptimeMillis();
4943        if (MONITOR_CPU_USAGE) {
4944            updateCpuStatsNow();
4945        }
4946
4947        synchronized (this) {
4948            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4949            if (mShuttingDown) {
4950                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4951                return;
4952            } else if (app.notResponding) {
4953                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4954                return;
4955            } else if (app.crashing) {
4956                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4957                return;
4958            }
4959
4960            // In case we come through here for the same app before completing
4961            // this one, mark as anring now so we will bail out.
4962            app.notResponding = true;
4963
4964            // Log the ANR to the event log.
4965            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4966                    app.processName, app.info.flags, annotation);
4967
4968            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4969            firstPids.add(app.pid);
4970
4971            int parentPid = app.pid;
4972            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4973            if (parentPid != app.pid) firstPids.add(parentPid);
4974
4975            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4976
4977            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4978                ProcessRecord r = mLruProcesses.get(i);
4979                if (r != null && r.thread != null) {
4980                    int pid = r.pid;
4981                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4982                        if (r.persistent) {
4983                            firstPids.add(pid);
4984                        } else {
4985                            lastPids.put(pid, Boolean.TRUE);
4986                        }
4987                    }
4988                }
4989            }
4990        }
4991
4992        // Log the ANR to the main log.
4993        StringBuilder info = new StringBuilder();
4994        info.setLength(0);
4995        info.append("ANR in ").append(app.processName);
4996        if (activity != null && activity.shortComponentName != null) {
4997            info.append(" (").append(activity.shortComponentName).append(")");
4998        }
4999        info.append("\n");
5000        info.append("PID: ").append(app.pid).append("\n");
5001        if (annotation != null) {
5002            info.append("Reason: ").append(annotation).append("\n");
5003        }
5004        if (parent != null && parent != activity) {
5005            info.append("Parent: ").append(parent.shortComponentName).append("\n");
5006        }
5007
5008        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
5009
5010        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
5011                NATIVE_STACKS_OF_INTEREST);
5012
5013        String cpuInfo = null;
5014        if (MONITOR_CPU_USAGE) {
5015            updateCpuStatsNow();
5016            synchronized (mProcessCpuTracker) {
5017                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
5018            }
5019            info.append(processCpuTracker.printCurrentLoad());
5020            info.append(cpuInfo);
5021        }
5022
5023        info.append(processCpuTracker.printCurrentState(anrTime));
5024
5025        Slog.e(TAG, info.toString());
5026        if (tracesFile == null) {
5027            // There is no trace file, so dump (only) the alleged culprit's threads to the log
5028            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
5029        }
5030
5031        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
5032                cpuInfo, tracesFile, null);
5033
5034        if (mController != null) {
5035            try {
5036                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
5037                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
5038                if (res != 0) {
5039                    if (res < 0 && app.pid != MY_PID) {
5040                        app.kill("anr", true);
5041                    } else {
5042                        synchronized (this) {
5043                            mServices.scheduleServiceTimeoutLocked(app);
5044                        }
5045                    }
5046                    return;
5047                }
5048            } catch (RemoteException e) {
5049                mController = null;
5050                Watchdog.getInstance().setActivityController(null);
5051            }
5052        }
5053
5054        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
5055        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
5056                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
5057
5058        synchronized (this) {
5059            mBatteryStatsService.noteProcessAnr(app.processName, app.uid);
5060
5061            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
5062                app.kill("bg anr", true);
5063                return;
5064            }
5065
5066            // Set the app's notResponding state, and look up the errorReportReceiver
5067            makeAppNotRespondingLocked(app,
5068                    activity != null ? activity.shortComponentName : null,
5069                    annotation != null ? "ANR " + annotation : "ANR",
5070                    info.toString());
5071
5072            // Bring up the infamous App Not Responding dialog
5073            Message msg = Message.obtain();
5074            HashMap<String, Object> map = new HashMap<String, Object>();
5075            msg.what = SHOW_NOT_RESPONDING_MSG;
5076            msg.obj = map;
5077            msg.arg1 = aboveSystem ? 1 : 0;
5078            map.put("app", app);
5079            if (activity != null) {
5080                map.put("activity", activity);
5081            }
5082
5083            mHandler.sendMessage(msg);
5084        }
5085    }
5086
5087    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5088        if (!mLaunchWarningShown) {
5089            mLaunchWarningShown = true;
5090            mHandler.post(new Runnable() {
5091                @Override
5092                public void run() {
5093                    synchronized (ActivityManagerService.this) {
5094                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5095                        d.show();
5096                        mHandler.postDelayed(new Runnable() {
5097                            @Override
5098                            public void run() {
5099                                synchronized (ActivityManagerService.this) {
5100                                    d.dismiss();
5101                                    mLaunchWarningShown = false;
5102                                }
5103                            }
5104                        }, 4000);
5105                    }
5106                }
5107            });
5108        }
5109    }
5110
5111    @Override
5112    public boolean clearApplicationUserData(final String packageName,
5113            final IPackageDataObserver observer, int userId) {
5114        enforceNotIsolatedCaller("clearApplicationUserData");
5115        int uid = Binder.getCallingUid();
5116        int pid = Binder.getCallingPid();
5117        userId = handleIncomingUser(pid, uid,
5118                userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5119        long callingId = Binder.clearCallingIdentity();
5120        try {
5121            IPackageManager pm = AppGlobals.getPackageManager();
5122            int pkgUid = -1;
5123            synchronized(this) {
5124                try {
5125                    pkgUid = pm.getPackageUid(packageName, userId);
5126                } catch (RemoteException e) {
5127                }
5128                if (pkgUid == -1) {
5129                    Slog.w(TAG, "Invalid packageName: " + packageName);
5130                    if (observer != null) {
5131                        try {
5132                            observer.onRemoveCompleted(packageName, false);
5133                        } catch (RemoteException e) {
5134                            Slog.i(TAG, "Observer no longer exists.");
5135                        }
5136                    }
5137                    return false;
5138                }
5139                if (uid == pkgUid || checkComponentPermission(
5140                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5141                        pid, uid, -1, true)
5142                        == PackageManager.PERMISSION_GRANTED) {
5143                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5144                } else {
5145                    throw new SecurityException("PID " + pid + " does not have permission "
5146                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5147                                    + " of package " + packageName);
5148                }
5149
5150                // Remove all tasks match the cleared application package and user
5151                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5152                    final TaskRecord tr = mRecentTasks.get(i);
5153                    final String taskPackageName =
5154                            tr.getBaseIntent().getComponent().getPackageName();
5155                    if (tr.userId != userId) continue;
5156                    if (!taskPackageName.equals(packageName)) continue;
5157                    removeTaskByIdLocked(tr.taskId, false);
5158                }
5159            }
5160
5161            try {
5162                // Clear application user data
5163                pm.clearApplicationUserData(packageName, observer, userId);
5164
5165                synchronized(this) {
5166                    // Remove all permissions granted from/to this package
5167                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5168                }
5169
5170                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5171                        Uri.fromParts("package", packageName, null));
5172                intent.putExtra(Intent.EXTRA_UID, pkgUid);
5173                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5174                        null, null, 0, null, null, null, false, false, userId);
5175            } catch (RemoteException e) {
5176            }
5177        } finally {
5178            Binder.restoreCallingIdentity(callingId);
5179        }
5180        return true;
5181    }
5182
5183    @Override
5184    public void killBackgroundProcesses(final String packageName, int userId) {
5185        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5186                != PackageManager.PERMISSION_GRANTED &&
5187                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5188                        != PackageManager.PERMISSION_GRANTED) {
5189            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5190                    + Binder.getCallingPid()
5191                    + ", uid=" + Binder.getCallingUid()
5192                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5193            Slog.w(TAG, msg);
5194            throw new SecurityException(msg);
5195        }
5196
5197        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5198                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5199        long callingId = Binder.clearCallingIdentity();
5200        try {
5201            IPackageManager pm = AppGlobals.getPackageManager();
5202            synchronized(this) {
5203                int appId = -1;
5204                try {
5205                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
5206                } catch (RemoteException e) {
5207                }
5208                if (appId == -1) {
5209                    Slog.w(TAG, "Invalid packageName: " + packageName);
5210                    return;
5211                }
5212                killPackageProcessesLocked(packageName, appId, userId,
5213                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5214            }
5215        } finally {
5216            Binder.restoreCallingIdentity(callingId);
5217        }
5218    }
5219
5220    @Override
5221    public void killAllBackgroundProcesses() {
5222        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5223                != PackageManager.PERMISSION_GRANTED) {
5224            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5225                    + Binder.getCallingPid()
5226                    + ", uid=" + Binder.getCallingUid()
5227                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5228            Slog.w(TAG, msg);
5229            throw new SecurityException(msg);
5230        }
5231
5232        long callingId = Binder.clearCallingIdentity();
5233        try {
5234            synchronized(this) {
5235                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5236                final int NP = mProcessNames.getMap().size();
5237                for (int ip=0; ip<NP; ip++) {
5238                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5239                    final int NA = apps.size();
5240                    for (int ia=0; ia<NA; ia++) {
5241                        ProcessRecord app = apps.valueAt(ia);
5242                        if (app.persistent) {
5243                            // we don't kill persistent processes
5244                            continue;
5245                        }
5246                        if (app.removed) {
5247                            procs.add(app);
5248                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5249                            app.removed = true;
5250                            procs.add(app);
5251                        }
5252                    }
5253                }
5254
5255                int N = procs.size();
5256                for (int i=0; i<N; i++) {
5257                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5258                }
5259                mAllowLowerMemLevel = true;
5260                updateOomAdjLocked();
5261                doLowMemReportIfNeededLocked(null);
5262            }
5263        } finally {
5264            Binder.restoreCallingIdentity(callingId);
5265        }
5266    }
5267
5268    @Override
5269    public void forceStopPackage(final String packageName, int userId) {
5270        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5271                != PackageManager.PERMISSION_GRANTED) {
5272            String msg = "Permission Denial: forceStopPackage() from pid="
5273                    + Binder.getCallingPid()
5274                    + ", uid=" + Binder.getCallingUid()
5275                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5276            Slog.w(TAG, msg);
5277            throw new SecurityException(msg);
5278        }
5279        final int callingPid = Binder.getCallingPid();
5280        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
5281                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5282        long callingId = Binder.clearCallingIdentity();
5283        try {
5284            IPackageManager pm = AppGlobals.getPackageManager();
5285            synchronized(this) {
5286                int[] users = userId == UserHandle.USER_ALL
5287                        ? getUsersLocked() : new int[] { userId };
5288                for (int user : users) {
5289                    int pkgUid = -1;
5290                    try {
5291                        pkgUid = pm.getPackageUid(packageName, user);
5292                    } catch (RemoteException e) {
5293                    }
5294                    if (pkgUid == -1) {
5295                        Slog.w(TAG, "Invalid packageName: " + packageName);
5296                        continue;
5297                    }
5298                    try {
5299                        pm.setPackageStoppedState(packageName, true, user);
5300                    } catch (RemoteException e) {
5301                    } catch (IllegalArgumentException e) {
5302                        Slog.w(TAG, "Failed trying to unstop package "
5303                                + packageName + ": " + e);
5304                    }
5305                    if (isUserRunningLocked(user, false)) {
5306                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5307                    }
5308                }
5309            }
5310        } finally {
5311            Binder.restoreCallingIdentity(callingId);
5312        }
5313    }
5314
5315    @Override
5316    public void addPackageDependency(String packageName) {
5317        synchronized (this) {
5318            int callingPid = Binder.getCallingPid();
5319            if (callingPid == Process.myPid()) {
5320                //  Yeah, um, no.
5321                return;
5322            }
5323            ProcessRecord proc;
5324            synchronized (mPidsSelfLocked) {
5325                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5326            }
5327            if (proc != null) {
5328                if (proc.pkgDeps == null) {
5329                    proc.pkgDeps = new ArraySet<String>(1);
5330                }
5331                proc.pkgDeps.add(packageName);
5332            }
5333        }
5334    }
5335
5336    /*
5337     * The pkg name and app id have to be specified.
5338     */
5339    @Override
5340    public void killApplicationWithAppId(String pkg, int appid, String reason) {
5341        if (pkg == null) {
5342            return;
5343        }
5344        // Make sure the uid is valid.
5345        if (appid < 0) {
5346            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5347            return;
5348        }
5349        int callerUid = Binder.getCallingUid();
5350        // Only the system server can kill an application
5351        if (callerUid == Process.SYSTEM_UID) {
5352            // Post an aysnc message to kill the application
5353            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5354            msg.arg1 = appid;
5355            msg.arg2 = 0;
5356            Bundle bundle = new Bundle();
5357            bundle.putString("pkg", pkg);
5358            bundle.putString("reason", reason);
5359            msg.obj = bundle;
5360            mHandler.sendMessage(msg);
5361        } else {
5362            throw new SecurityException(callerUid + " cannot kill pkg: " +
5363                    pkg);
5364        }
5365    }
5366
5367    @Override
5368    public void closeSystemDialogs(String reason) {
5369        enforceNotIsolatedCaller("closeSystemDialogs");
5370
5371        final int pid = Binder.getCallingPid();
5372        final int uid = Binder.getCallingUid();
5373        final long origId = Binder.clearCallingIdentity();
5374        try {
5375            synchronized (this) {
5376                // Only allow this from foreground processes, so that background
5377                // applications can't abuse it to prevent system UI from being shown.
5378                if (uid >= Process.FIRST_APPLICATION_UID) {
5379                    ProcessRecord proc;
5380                    synchronized (mPidsSelfLocked) {
5381                        proc = mPidsSelfLocked.get(pid);
5382                    }
5383                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5384                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5385                                + " from background process " + proc);
5386                        return;
5387                    }
5388                }
5389                closeSystemDialogsLocked(reason);
5390            }
5391        } finally {
5392            Binder.restoreCallingIdentity(origId);
5393        }
5394    }
5395
5396    void closeSystemDialogsLocked(String reason) {
5397        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5398        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5399                | Intent.FLAG_RECEIVER_FOREGROUND);
5400        if (reason != null) {
5401            intent.putExtra("reason", reason);
5402        }
5403        mWindowManager.closeSystemDialogs(reason);
5404
5405        mStackSupervisor.closeSystemDialogsLocked();
5406
5407        broadcastIntentLocked(null, null, intent, null,
5408                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
5409                Process.SYSTEM_UID, UserHandle.USER_ALL);
5410    }
5411
5412    @Override
5413    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5414        enforceNotIsolatedCaller("getProcessMemoryInfo");
5415        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5416        for (int i=pids.length-1; i>=0; i--) {
5417            ProcessRecord proc;
5418            int oomAdj;
5419            synchronized (this) {
5420                synchronized (mPidsSelfLocked) {
5421                    proc = mPidsSelfLocked.get(pids[i]);
5422                    oomAdj = proc != null ? proc.setAdj : 0;
5423                }
5424            }
5425            infos[i] = new Debug.MemoryInfo();
5426            Debug.getMemoryInfo(pids[i], infos[i]);
5427            if (proc != null) {
5428                synchronized (this) {
5429                    if (proc.thread != null && proc.setAdj == oomAdj) {
5430                        // Record this for posterity if the process has been stable.
5431                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5432                                infos[i].getTotalUss(), false, proc.pkgList);
5433                    }
5434                }
5435            }
5436        }
5437        return infos;
5438    }
5439
5440    @Override
5441    public long[] getProcessPss(int[] pids) {
5442        enforceNotIsolatedCaller("getProcessPss");
5443        long[] pss = new long[pids.length];
5444        for (int i=pids.length-1; i>=0; i--) {
5445            ProcessRecord proc;
5446            int oomAdj;
5447            synchronized (this) {
5448                synchronized (mPidsSelfLocked) {
5449                    proc = mPidsSelfLocked.get(pids[i]);
5450                    oomAdj = proc != null ? proc.setAdj : 0;
5451                }
5452            }
5453            long[] tmpUss = new long[1];
5454            pss[i] = Debug.getPss(pids[i], tmpUss, null);
5455            if (proc != null) {
5456                synchronized (this) {
5457                    if (proc.thread != null && proc.setAdj == oomAdj) {
5458                        // Record this for posterity if the process has been stable.
5459                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5460                    }
5461                }
5462            }
5463        }
5464        return pss;
5465    }
5466
5467    @Override
5468    public void killApplicationProcess(String processName, int uid) {
5469        if (processName == null) {
5470            return;
5471        }
5472
5473        int callerUid = Binder.getCallingUid();
5474        // Only the system server can kill an application
5475        if (callerUid == Process.SYSTEM_UID) {
5476            synchronized (this) {
5477                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5478                if (app != null && app.thread != null) {
5479                    try {
5480                        app.thread.scheduleSuicide();
5481                    } catch (RemoteException e) {
5482                        // If the other end already died, then our work here is done.
5483                    }
5484                } else {
5485                    Slog.w(TAG, "Process/uid not found attempting kill of "
5486                            + processName + " / " + uid);
5487                }
5488            }
5489        } else {
5490            throw new SecurityException(callerUid + " cannot kill app process: " +
5491                    processName);
5492        }
5493    }
5494
5495    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5496        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5497                false, true, false, false, UserHandle.getUserId(uid), reason);
5498        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5499                Uri.fromParts("package", packageName, null));
5500        if (!mProcessesReady) {
5501            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5502                    | Intent.FLAG_RECEIVER_FOREGROUND);
5503        }
5504        intent.putExtra(Intent.EXTRA_UID, uid);
5505        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5506        broadcastIntentLocked(null, null, intent,
5507                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5508                false, false,
5509                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5510    }
5511
5512    private void forceStopUserLocked(int userId, String reason) {
5513        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
5514        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
5515        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5516                | Intent.FLAG_RECEIVER_FOREGROUND);
5517        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5518        broadcastIntentLocked(null, null, intent,
5519                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5520                false, false,
5521                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
5522    }
5523
5524    private final boolean killPackageProcessesLocked(String packageName, int appId,
5525            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5526            boolean doit, boolean evenPersistent, String reason) {
5527        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5528
5529        // Remove all processes this package may have touched: all with the
5530        // same UID (except for the system or root user), and all whose name
5531        // matches the package name.
5532        final int NP = mProcessNames.getMap().size();
5533        for (int ip=0; ip<NP; ip++) {
5534            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5535            final int NA = apps.size();
5536            for (int ia=0; ia<NA; ia++) {
5537                ProcessRecord app = apps.valueAt(ia);
5538                if (app.persistent && !evenPersistent) {
5539                    // we don't kill persistent processes
5540                    continue;
5541                }
5542                if (app.removed) {
5543                    if (doit) {
5544                        procs.add(app);
5545                    }
5546                    continue;
5547                }
5548
5549                // Skip process if it doesn't meet our oom adj requirement.
5550                if (app.setAdj < minOomAdj) {
5551                    continue;
5552                }
5553
5554                // If no package is specified, we call all processes under the
5555                // give user id.
5556                if (packageName == null) {
5557                    if (app.userId != userId) {
5558                        continue;
5559                    }
5560                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5561                        continue;
5562                    }
5563                // Package has been specified, we want to hit all processes
5564                // that match it.  We need to qualify this by the processes
5565                // that are running under the specified app and user ID.
5566                } else {
5567                    final boolean isDep = app.pkgDeps != null
5568                            && app.pkgDeps.contains(packageName);
5569                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5570                        continue;
5571                    }
5572                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5573                        continue;
5574                    }
5575                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5576                        continue;
5577                    }
5578                }
5579
5580                // Process has passed all conditions, kill it!
5581                if (!doit) {
5582                    return true;
5583                }
5584                app.removed = true;
5585                procs.add(app);
5586            }
5587        }
5588
5589        int N = procs.size();
5590        for (int i=0; i<N; i++) {
5591            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5592        }
5593        updateOomAdjLocked();
5594        return N > 0;
5595    }
5596
5597    private final boolean forceStopPackageLocked(String name, int appId,
5598            boolean callerWillRestart, boolean purgeCache, boolean doit,
5599            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5600        int i;
5601        int N;
5602
5603        if (userId == UserHandle.USER_ALL && name == null) {
5604            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5605        }
5606
5607        if (appId < 0 && name != null) {
5608            try {
5609                appId = UserHandle.getAppId(
5610                        AppGlobals.getPackageManager().getPackageUid(name, 0));
5611            } catch (RemoteException e) {
5612            }
5613        }
5614
5615        if (doit) {
5616            if (name != null) {
5617                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
5618                        + " user=" + userId + ": " + reason);
5619            } else {
5620                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5621            }
5622
5623            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5624            for (int ip=pmap.size()-1; ip>=0; ip--) {
5625                SparseArray<Long> ba = pmap.valueAt(ip);
5626                for (i=ba.size()-1; i>=0; i--) {
5627                    boolean remove = false;
5628                    final int entUid = ba.keyAt(i);
5629                    if (name != null) {
5630                        if (userId == UserHandle.USER_ALL) {
5631                            if (UserHandle.getAppId(entUid) == appId) {
5632                                remove = true;
5633                            }
5634                        } else {
5635                            if (entUid == UserHandle.getUid(userId, appId)) {
5636                                remove = true;
5637                            }
5638                        }
5639                    } else if (UserHandle.getUserId(entUid) == userId) {
5640                        remove = true;
5641                    }
5642                    if (remove) {
5643                        ba.removeAt(i);
5644                    }
5645                }
5646                if (ba.size() == 0) {
5647                    pmap.removeAt(ip);
5648                }
5649            }
5650        }
5651
5652        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
5653                -100, callerWillRestart, true, doit, evenPersistent,
5654                name == null ? ("stop user " + userId) : ("stop " + name));
5655
5656        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
5657            if (!doit) {
5658                return true;
5659            }
5660            didSomething = true;
5661        }
5662
5663        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
5664            if (!doit) {
5665                return true;
5666            }
5667            didSomething = true;
5668        }
5669
5670        if (name == null) {
5671            // Remove all sticky broadcasts from this user.
5672            mStickyBroadcasts.remove(userId);
5673        }
5674
5675        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
5676        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
5677                userId, providers)) {
5678            if (!doit) {
5679                return true;
5680            }
5681            didSomething = true;
5682        }
5683        N = providers.size();
5684        for (i=0; i<N; i++) {
5685            removeDyingProviderLocked(null, providers.get(i), true);
5686        }
5687
5688        // Remove transient permissions granted from/to this package/user
5689        removeUriPermissionsForPackageLocked(name, userId, false);
5690
5691        if (name == null || uninstalling) {
5692            // Remove pending intents.  For now we only do this when force
5693            // stopping users, because we have some problems when doing this
5694            // for packages -- app widgets are not currently cleaned up for
5695            // such packages, so they can be left with bad pending intents.
5696            if (mIntentSenderRecords.size() > 0) {
5697                Iterator<WeakReference<PendingIntentRecord>> it
5698                        = mIntentSenderRecords.values().iterator();
5699                while (it.hasNext()) {
5700                    WeakReference<PendingIntentRecord> wpir = it.next();
5701                    if (wpir == null) {
5702                        it.remove();
5703                        continue;
5704                    }
5705                    PendingIntentRecord pir = wpir.get();
5706                    if (pir == null) {
5707                        it.remove();
5708                        continue;
5709                    }
5710                    if (name == null) {
5711                        // Stopping user, remove all objects for the user.
5712                        if (pir.key.userId != userId) {
5713                            // Not the same user, skip it.
5714                            continue;
5715                        }
5716                    } else {
5717                        if (UserHandle.getAppId(pir.uid) != appId) {
5718                            // Different app id, skip it.
5719                            continue;
5720                        }
5721                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5722                            // Different user, skip it.
5723                            continue;
5724                        }
5725                        if (!pir.key.packageName.equals(name)) {
5726                            // Different package, skip it.
5727                            continue;
5728                        }
5729                    }
5730                    if (!doit) {
5731                        return true;
5732                    }
5733                    didSomething = true;
5734                    it.remove();
5735                    pir.canceled = true;
5736                    if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
5737                        pir.key.activity.pendingResults.remove(pir.ref);
5738                    }
5739                }
5740            }
5741        }
5742
5743        if (doit) {
5744            if (purgeCache && name != null) {
5745                AttributeCache ac = AttributeCache.instance();
5746                if (ac != null) {
5747                    ac.removePackage(name);
5748                }
5749            }
5750            if (mBooted) {
5751                mStackSupervisor.resumeTopActivitiesLocked();
5752                mStackSupervisor.scheduleIdleLocked();
5753            }
5754        }
5755
5756        return didSomething;
5757    }
5758
5759    private final boolean removeProcessLocked(ProcessRecord app,
5760            boolean callerWillRestart, boolean allowRestart, String reason) {
5761        final String name = app.processName;
5762        final int uid = app.uid;
5763        if (DEBUG_PROCESSES) Slog.d(
5764            TAG, "Force removing proc " + app.toShortString() + " (" + name
5765            + "/" + uid + ")");
5766
5767        mProcessNames.remove(name, uid);
5768        mIsolatedProcesses.remove(app.uid);
5769        if (mHeavyWeightProcess == app) {
5770            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5771                    mHeavyWeightProcess.userId, 0));
5772            mHeavyWeightProcess = null;
5773        }
5774        boolean needRestart = false;
5775        if (app.pid > 0 && app.pid != MY_PID) {
5776            int pid = app.pid;
5777            synchronized (mPidsSelfLocked) {
5778                mPidsSelfLocked.remove(pid);
5779                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5780            }
5781            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5782            if (app.isolated) {
5783                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5784            }
5785            app.kill(reason, true);
5786            handleAppDiedLocked(app, true, allowRestart);
5787            removeLruProcessLocked(app);
5788
5789            if (app.persistent && !app.isolated) {
5790                if (!callerWillRestart) {
5791                    addAppLocked(app.info, false, null /* ABI override */);
5792                } else {
5793                    needRestart = true;
5794                }
5795            }
5796        } else {
5797            mRemovedProcesses.add(app);
5798        }
5799
5800        return needRestart;
5801    }
5802
5803    private final void processStartTimedOutLocked(ProcessRecord app) {
5804        final int pid = app.pid;
5805        boolean gone = false;
5806        synchronized (mPidsSelfLocked) {
5807            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5808            if (knownApp != null && knownApp.thread == null) {
5809                mPidsSelfLocked.remove(pid);
5810                gone = true;
5811            }
5812        }
5813
5814        if (gone) {
5815            Slog.w(TAG, "Process " + app + " failed to attach");
5816            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5817                    pid, app.uid, app.processName);
5818            mProcessNames.remove(app.processName, app.uid);
5819            mIsolatedProcesses.remove(app.uid);
5820            if (mHeavyWeightProcess == app) {
5821                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5822                        mHeavyWeightProcess.userId, 0));
5823                mHeavyWeightProcess = null;
5824            }
5825            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5826            if (app.isolated) {
5827                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5828            }
5829            // Take care of any launching providers waiting for this process.
5830            checkAppInLaunchingProvidersLocked(app, true);
5831            // Take care of any services that are waiting for the process.
5832            mServices.processStartTimedOutLocked(app);
5833            app.kill("start timeout", true);
5834            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5835                Slog.w(TAG, "Unattached app died before backup, skipping");
5836                try {
5837                    IBackupManager bm = IBackupManager.Stub.asInterface(
5838                            ServiceManager.getService(Context.BACKUP_SERVICE));
5839                    bm.agentDisconnected(app.info.packageName);
5840                } catch (RemoteException e) {
5841                    // Can't happen; the backup manager is local
5842                }
5843            }
5844            if (isPendingBroadcastProcessLocked(pid)) {
5845                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5846                skipPendingBroadcastLocked(pid);
5847            }
5848        } else {
5849            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5850        }
5851    }
5852
5853    private final boolean attachApplicationLocked(IApplicationThread thread,
5854            int pid) {
5855
5856        // Find the application record that is being attached...  either via
5857        // the pid if we are running in multiple processes, or just pull the
5858        // next app record if we are emulating process with anonymous threads.
5859        ProcessRecord app;
5860        if (pid != MY_PID && pid >= 0) {
5861            synchronized (mPidsSelfLocked) {
5862                app = mPidsSelfLocked.get(pid);
5863            }
5864        } else {
5865            app = null;
5866        }
5867
5868        if (app == null) {
5869            Slog.w(TAG, "No pending application record for pid " + pid
5870                    + " (IApplicationThread " + thread + "); dropping process");
5871            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5872            if (pid > 0 && pid != MY_PID) {
5873                Process.killProcessQuiet(pid);
5874                //TODO: Process.killProcessGroup(app.info.uid, pid);
5875            } else {
5876                try {
5877                    thread.scheduleExit();
5878                } catch (Exception e) {
5879                    // Ignore exceptions.
5880                }
5881            }
5882            return false;
5883        }
5884
5885        // If this application record is still attached to a previous
5886        // process, clean it up now.
5887        if (app.thread != null) {
5888            handleAppDiedLocked(app, true, true);
5889        }
5890
5891        // Tell the process all about itself.
5892
5893        if (localLOGV) Slog.v(
5894                TAG, "Binding process pid " + pid + " to record " + app);
5895
5896        final String processName = app.processName;
5897        try {
5898            AppDeathRecipient adr = new AppDeathRecipient(
5899                    app, pid, thread);
5900            thread.asBinder().linkToDeath(adr, 0);
5901            app.deathRecipient = adr;
5902        } catch (RemoteException e) {
5903            app.resetPackageList(mProcessStats);
5904            startProcessLocked(app, "link fail", processName);
5905            return false;
5906        }
5907
5908        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5909
5910        app.makeActive(thread, mProcessStats);
5911        app.curAdj = app.setAdj = -100;
5912        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5913        app.forcingToForeground = null;
5914        updateProcessForegroundLocked(app, false, false);
5915        app.hasShownUi = false;
5916        app.debugging = false;
5917        app.cached = false;
5918        app.killedByAm = false;
5919
5920        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5921
5922        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5923        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5924
5925        if (!normalMode) {
5926            Slog.i(TAG, "Launching preboot mode app: " + app);
5927        }
5928
5929        if (localLOGV) Slog.v(
5930            TAG, "New app record " + app
5931            + " thread=" + thread.asBinder() + " pid=" + pid);
5932        try {
5933            int testMode = IApplicationThread.DEBUG_OFF;
5934            if (mDebugApp != null && mDebugApp.equals(processName)) {
5935                testMode = mWaitForDebugger
5936                    ? IApplicationThread.DEBUG_WAIT
5937                    : IApplicationThread.DEBUG_ON;
5938                app.debugging = true;
5939                if (mDebugTransient) {
5940                    mDebugApp = mOrigDebugApp;
5941                    mWaitForDebugger = mOrigWaitForDebugger;
5942                }
5943            }
5944            String profileFile = app.instrumentationProfileFile;
5945            ParcelFileDescriptor profileFd = null;
5946            int samplingInterval = 0;
5947            boolean profileAutoStop = false;
5948            if (mProfileApp != null && mProfileApp.equals(processName)) {
5949                mProfileProc = app;
5950                profileFile = mProfileFile;
5951                profileFd = mProfileFd;
5952                samplingInterval = mSamplingInterval;
5953                profileAutoStop = mAutoStopProfiler;
5954            }
5955            boolean enableOpenGlTrace = false;
5956            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
5957                enableOpenGlTrace = true;
5958                mOpenGlTraceApp = null;
5959            }
5960
5961            // If the app is being launched for restore or full backup, set it up specially
5962            boolean isRestrictedBackupMode = false;
5963            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
5964                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
5965                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
5966                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
5967            }
5968
5969            ensurePackageDexOpt(app.instrumentationInfo != null
5970                    ? app.instrumentationInfo.packageName
5971                    : app.info.packageName);
5972            if (app.instrumentationClass != null) {
5973                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
5974            }
5975            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
5976                    + processName + " with config " + mConfiguration);
5977            ApplicationInfo appInfo = app.instrumentationInfo != null
5978                    ? app.instrumentationInfo : app.info;
5979            app.compat = compatibilityInfoForPackageLocked(appInfo);
5980            if (profileFd != null) {
5981                profileFd = profileFd.dup();
5982            }
5983            ProfilerInfo profilerInfo = profileFile == null ? null
5984                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
5985            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
5986                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
5987                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
5988                    isRestrictedBackupMode || !normalMode, app.persistent,
5989                    new Configuration(mConfiguration), app.compat,
5990                    getCommonServicesLocked(app.isolated),
5991                    mCoreSettingsObserver.getCoreSettingsLocked());
5992            updateLruProcessLocked(app, false, null);
5993            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
5994        } catch (Exception e) {
5995            // todo: Yikes!  What should we do?  For now we will try to
5996            // start another process, but that could easily get us in
5997            // an infinite loop of restarting processes...
5998            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
5999
6000            app.resetPackageList(mProcessStats);
6001            app.unlinkDeathRecipient();
6002            startProcessLocked(app, "bind fail", processName);
6003            return false;
6004        }
6005
6006        // Remove this record from the list of starting applications.
6007        mPersistentStartingProcesses.remove(app);
6008        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
6009                "Attach application locked removing on hold: " + app);
6010        mProcessesOnHold.remove(app);
6011
6012        boolean badApp = false;
6013        boolean didSomething = false;
6014
6015        // See if the top visible activity is waiting to run in this process...
6016        if (normalMode) {
6017            try {
6018                if (mStackSupervisor.attachApplicationLocked(app)) {
6019                    didSomething = true;
6020                }
6021            } catch (Exception e) {
6022                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6023                badApp = true;
6024            }
6025        }
6026
6027        // Find any services that should be running in this process...
6028        if (!badApp) {
6029            try {
6030                didSomething |= mServices.attachApplicationLocked(app, processName);
6031            } catch (Exception e) {
6032                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6033                badApp = true;
6034            }
6035        }
6036
6037        // Check if a next-broadcast receiver is in this process...
6038        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6039            try {
6040                didSomething |= sendPendingBroadcastsLocked(app);
6041            } catch (Exception e) {
6042                // If the app died trying to launch the receiver we declare it 'bad'
6043                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6044                badApp = true;
6045            }
6046        }
6047
6048        // Check whether the next backup agent is in this process...
6049        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6050            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
6051            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
6052            try {
6053                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6054                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6055                        mBackupTarget.backupMode);
6056            } catch (Exception e) {
6057                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6058                badApp = true;
6059            }
6060        }
6061
6062        if (badApp) {
6063            app.kill("error during init", true);
6064            handleAppDiedLocked(app, false, true);
6065            return false;
6066        }
6067
6068        if (!didSomething) {
6069            updateOomAdjLocked();
6070        }
6071
6072        return true;
6073    }
6074
6075    @Override
6076    public final void attachApplication(IApplicationThread thread) {
6077        synchronized (this) {
6078            int callingPid = Binder.getCallingPid();
6079            final long origId = Binder.clearCallingIdentity();
6080            attachApplicationLocked(thread, callingPid);
6081            Binder.restoreCallingIdentity(origId);
6082        }
6083    }
6084
6085    @Override
6086    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6087        final long origId = Binder.clearCallingIdentity();
6088        synchronized (this) {
6089            ActivityStack stack = ActivityRecord.getStackLocked(token);
6090            if (stack != null) {
6091                ActivityRecord r =
6092                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6093                if (stopProfiling) {
6094                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6095                        try {
6096                            mProfileFd.close();
6097                        } catch (IOException e) {
6098                        }
6099                        clearProfilerLocked();
6100                    }
6101                }
6102            }
6103        }
6104        Binder.restoreCallingIdentity(origId);
6105    }
6106
6107    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6108        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6109                finishBooting? 1 : 0, enableScreen ? 1 : 0));
6110    }
6111
6112    void enableScreenAfterBoot() {
6113        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6114                SystemClock.uptimeMillis());
6115        mWindowManager.enableScreenAfterBoot();
6116
6117        synchronized (this) {
6118            updateEventDispatchingLocked();
6119        }
6120    }
6121
6122    @Override
6123    public void showBootMessage(final CharSequence msg, final boolean always) {
6124        enforceNotIsolatedCaller("showBootMessage");
6125        mWindowManager.showBootMessage(msg, always);
6126    }
6127
6128    @Override
6129    public void keyguardWaitingForActivityDrawn() {
6130        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6131        final long token = Binder.clearCallingIdentity();
6132        try {
6133            synchronized (this) {
6134                if (DEBUG_LOCKSCREEN) logLockScreen("");
6135                mWindowManager.keyguardWaitingForActivityDrawn();
6136                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6137                    mLockScreenShown = LOCK_SCREEN_LEAVING;
6138                    updateSleepIfNeededLocked();
6139                }
6140            }
6141        } finally {
6142            Binder.restoreCallingIdentity(token);
6143        }
6144    }
6145
6146    final void finishBooting() {
6147        synchronized (this) {
6148            if (!mBootAnimationComplete) {
6149                mCallFinishBooting = true;
6150                return;
6151            }
6152            mCallFinishBooting = false;
6153        }
6154
6155        ArraySet<String> completedIsas = new ArraySet<String>();
6156        for (String abi : Build.SUPPORTED_ABIS) {
6157            Process.establishZygoteConnectionForAbi(abi);
6158            final String instructionSet = VMRuntime.getInstructionSet(abi);
6159            if (!completedIsas.contains(instructionSet)) {
6160                if (mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi)) != 0) {
6161                    Slog.e(TAG, "Unable to mark boot complete for abi: " + abi);
6162                }
6163                completedIsas.add(instructionSet);
6164            }
6165        }
6166
6167        IntentFilter pkgFilter = new IntentFilter();
6168        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6169        pkgFilter.addDataScheme("package");
6170        mContext.registerReceiver(new BroadcastReceiver() {
6171            @Override
6172            public void onReceive(Context context, Intent intent) {
6173                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6174                if (pkgs != null) {
6175                    for (String pkg : pkgs) {
6176                        synchronized (ActivityManagerService.this) {
6177                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6178                                    0, "finished booting")) {
6179                                setResultCode(Activity.RESULT_OK);
6180                                return;
6181                            }
6182                        }
6183                    }
6184                }
6185            }
6186        }, pkgFilter);
6187
6188        // Let system services know.
6189        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6190
6191        synchronized (this) {
6192            // Ensure that any processes we had put on hold are now started
6193            // up.
6194            final int NP = mProcessesOnHold.size();
6195            if (NP > 0) {
6196                ArrayList<ProcessRecord> procs =
6197                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6198                for (int ip=0; ip<NP; ip++) {
6199                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
6200                            + procs.get(ip));
6201                    startProcessLocked(procs.get(ip), "on-hold", null);
6202                }
6203            }
6204
6205            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6206                // Start looking for apps that are abusing wake locks.
6207                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6208                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6209                // Tell anyone interested that we are done booting!
6210                SystemProperties.set("sys.boot_completed", "1");
6211
6212                // And trigger dev.bootcomplete if we are not showing encryption progress
6213                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6214                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6215                    SystemProperties.set("dev.bootcomplete", "1");
6216                }
6217                for (int i=0; i<mStartedUsers.size(); i++) {
6218                    UserStartedState uss = mStartedUsers.valueAt(i);
6219                    if (uss.mState == UserStartedState.STATE_BOOTING) {
6220                        uss.mState = UserStartedState.STATE_RUNNING;
6221                        final int userId = mStartedUsers.keyAt(i);
6222                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
6223                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
6224                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
6225                        broadcastIntentLocked(null, null, intent, null,
6226                                new IIntentReceiver.Stub() {
6227                                    @Override
6228                                    public void performReceive(Intent intent, int resultCode,
6229                                            String data, Bundle extras, boolean ordered,
6230                                            boolean sticky, int sendingUser) {
6231                                        synchronized (ActivityManagerService.this) {
6232                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6233                                                    true, false);
6234                                        }
6235                                    }
6236                                },
6237                                0, null, null,
6238                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
6239                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
6240                                userId);
6241                    }
6242                }
6243                scheduleStartProfilesLocked();
6244            }
6245        }
6246    }
6247
6248    @Override
6249    public void bootAnimationComplete() {
6250        final boolean callFinishBooting;
6251        synchronized (this) {
6252            callFinishBooting = mCallFinishBooting;
6253            mBootAnimationComplete = true;
6254        }
6255        if (callFinishBooting) {
6256            finishBooting();
6257        }
6258    }
6259
6260    @Override
6261    public void systemBackupRestored() {
6262        synchronized (this) {
6263            if (mSystemReady) {
6264                mTaskPersister.restoreTasksFromOtherDeviceLocked();
6265            } else {
6266                Slog.w(TAG, "System backup restored before system is ready");
6267            }
6268        }
6269    }
6270
6271    final void ensureBootCompleted() {
6272        boolean booting;
6273        boolean enableScreen;
6274        synchronized (this) {
6275            booting = mBooting;
6276            mBooting = false;
6277            enableScreen = !mBooted;
6278            mBooted = true;
6279        }
6280
6281        if (booting) {
6282            finishBooting();
6283        }
6284
6285        if (enableScreen) {
6286            enableScreenAfterBoot();
6287        }
6288    }
6289
6290    @Override
6291    public final void activityResumed(IBinder token) {
6292        final long origId = Binder.clearCallingIdentity();
6293        synchronized(this) {
6294            ActivityStack stack = ActivityRecord.getStackLocked(token);
6295            if (stack != null) {
6296                ActivityRecord.activityResumedLocked(token);
6297            }
6298        }
6299        Binder.restoreCallingIdentity(origId);
6300    }
6301
6302    @Override
6303    public final void activityPaused(IBinder token) {
6304        final long origId = Binder.clearCallingIdentity();
6305        synchronized(this) {
6306            ActivityStack stack = ActivityRecord.getStackLocked(token);
6307            if (stack != null) {
6308                stack.activityPausedLocked(token, false);
6309            }
6310        }
6311        Binder.restoreCallingIdentity(origId);
6312    }
6313
6314    @Override
6315    public final void activityStopped(IBinder token, Bundle icicle,
6316            PersistableBundle persistentState, CharSequence description) {
6317        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
6318
6319        // Refuse possible leaked file descriptors
6320        if (icicle != null && icicle.hasFileDescriptors()) {
6321            throw new IllegalArgumentException("File descriptors passed in Bundle");
6322        }
6323
6324        final long origId = Binder.clearCallingIdentity();
6325
6326        synchronized (this) {
6327            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6328            if (r != null) {
6329                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6330            }
6331        }
6332
6333        trimApplications();
6334
6335        Binder.restoreCallingIdentity(origId);
6336    }
6337
6338    @Override
6339    public final void activityDestroyed(IBinder token) {
6340        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
6341        synchronized (this) {
6342            ActivityStack stack = ActivityRecord.getStackLocked(token);
6343            if (stack != null) {
6344                stack.activityDestroyedLocked(token);
6345            }
6346        }
6347    }
6348
6349    @Override
6350    public final void backgroundResourcesReleased(IBinder token) {
6351        final long origId = Binder.clearCallingIdentity();
6352        try {
6353            synchronized (this) {
6354                ActivityStack stack = ActivityRecord.getStackLocked(token);
6355                if (stack != null) {
6356                    stack.backgroundResourcesReleased();
6357                }
6358            }
6359        } finally {
6360            Binder.restoreCallingIdentity(origId);
6361        }
6362    }
6363
6364    @Override
6365    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6366        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6367    }
6368
6369    @Override
6370    public final void notifyEnterAnimationComplete(IBinder token) {
6371        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6372    }
6373
6374    @Override
6375    public String getCallingPackage(IBinder token) {
6376        synchronized (this) {
6377            ActivityRecord r = getCallingRecordLocked(token);
6378            return r != null ? r.info.packageName : null;
6379        }
6380    }
6381
6382    @Override
6383    public ComponentName getCallingActivity(IBinder token) {
6384        synchronized (this) {
6385            ActivityRecord r = getCallingRecordLocked(token);
6386            return r != null ? r.intent.getComponent() : null;
6387        }
6388    }
6389
6390    private ActivityRecord getCallingRecordLocked(IBinder token) {
6391        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6392        if (r == null) {
6393            return null;
6394        }
6395        return r.resultTo;
6396    }
6397
6398    @Override
6399    public ComponentName getActivityClassForToken(IBinder token) {
6400        synchronized(this) {
6401            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6402            if (r == null) {
6403                return null;
6404            }
6405            return r.intent.getComponent();
6406        }
6407    }
6408
6409    @Override
6410    public String getPackageForToken(IBinder token) {
6411        synchronized(this) {
6412            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6413            if (r == null) {
6414                return null;
6415            }
6416            return r.packageName;
6417        }
6418    }
6419
6420    @Override
6421    public IIntentSender getIntentSender(int type,
6422            String packageName, IBinder token, String resultWho,
6423            int requestCode, Intent[] intents, String[] resolvedTypes,
6424            int flags, Bundle options, int userId) {
6425        enforceNotIsolatedCaller("getIntentSender");
6426        // Refuse possible leaked file descriptors
6427        if (intents != null) {
6428            if (intents.length < 1) {
6429                throw new IllegalArgumentException("Intents array length must be >= 1");
6430            }
6431            for (int i=0; i<intents.length; i++) {
6432                Intent intent = intents[i];
6433                if (intent != null) {
6434                    if (intent.hasFileDescriptors()) {
6435                        throw new IllegalArgumentException("File descriptors passed in Intent");
6436                    }
6437                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6438                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6439                        throw new IllegalArgumentException(
6440                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6441                    }
6442                    intents[i] = new Intent(intent);
6443                }
6444            }
6445            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6446                throw new IllegalArgumentException(
6447                        "Intent array length does not match resolvedTypes length");
6448            }
6449        }
6450        if (options != null) {
6451            if (options.hasFileDescriptors()) {
6452                throw new IllegalArgumentException("File descriptors passed in options");
6453            }
6454        }
6455
6456        synchronized(this) {
6457            int callingUid = Binder.getCallingUid();
6458            int origUserId = userId;
6459            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6460                    type == ActivityManager.INTENT_SENDER_BROADCAST,
6461                    ALLOW_NON_FULL, "getIntentSender", null);
6462            if (origUserId == UserHandle.USER_CURRENT) {
6463                // We don't want to evaluate this until the pending intent is
6464                // actually executed.  However, we do want to always do the
6465                // security checking for it above.
6466                userId = UserHandle.USER_CURRENT;
6467            }
6468            try {
6469                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6470                    int uid = AppGlobals.getPackageManager()
6471                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
6472                    if (!UserHandle.isSameApp(callingUid, uid)) {
6473                        String msg = "Permission Denial: getIntentSender() from pid="
6474                            + Binder.getCallingPid()
6475                            + ", uid=" + Binder.getCallingUid()
6476                            + ", (need uid=" + uid + ")"
6477                            + " is not allowed to send as package " + packageName;
6478                        Slog.w(TAG, msg);
6479                        throw new SecurityException(msg);
6480                    }
6481                }
6482
6483                return getIntentSenderLocked(type, packageName, callingUid, userId,
6484                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
6485
6486            } catch (RemoteException e) {
6487                throw new SecurityException(e);
6488            }
6489        }
6490    }
6491
6492    IIntentSender getIntentSenderLocked(int type, String packageName,
6493            int callingUid, int userId, IBinder token, String resultWho,
6494            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6495            Bundle options) {
6496        if (DEBUG_MU)
6497            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6498        ActivityRecord activity = null;
6499        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6500            activity = ActivityRecord.isInStackLocked(token);
6501            if (activity == null) {
6502                return null;
6503            }
6504            if (activity.finishing) {
6505                return null;
6506            }
6507        }
6508
6509        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6510        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6511        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6512        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6513                |PendingIntent.FLAG_UPDATE_CURRENT);
6514
6515        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6516                type, packageName, activity, resultWho,
6517                requestCode, intents, resolvedTypes, flags, options, userId);
6518        WeakReference<PendingIntentRecord> ref;
6519        ref = mIntentSenderRecords.get(key);
6520        PendingIntentRecord rec = ref != null ? ref.get() : null;
6521        if (rec != null) {
6522            if (!cancelCurrent) {
6523                if (updateCurrent) {
6524                    if (rec.key.requestIntent != null) {
6525                        rec.key.requestIntent.replaceExtras(intents != null ?
6526                                intents[intents.length - 1] : null);
6527                    }
6528                    if (intents != null) {
6529                        intents[intents.length-1] = rec.key.requestIntent;
6530                        rec.key.allIntents = intents;
6531                        rec.key.allResolvedTypes = resolvedTypes;
6532                    } else {
6533                        rec.key.allIntents = null;
6534                        rec.key.allResolvedTypes = null;
6535                    }
6536                }
6537                return rec;
6538            }
6539            rec.canceled = true;
6540            mIntentSenderRecords.remove(key);
6541        }
6542        if (noCreate) {
6543            return rec;
6544        }
6545        rec = new PendingIntentRecord(this, key, callingUid);
6546        mIntentSenderRecords.put(key, rec.ref);
6547        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6548            if (activity.pendingResults == null) {
6549                activity.pendingResults
6550                        = new HashSet<WeakReference<PendingIntentRecord>>();
6551            }
6552            activity.pendingResults.add(rec.ref);
6553        }
6554        return rec;
6555    }
6556
6557    @Override
6558    public void cancelIntentSender(IIntentSender sender) {
6559        if (!(sender instanceof PendingIntentRecord)) {
6560            return;
6561        }
6562        synchronized(this) {
6563            PendingIntentRecord rec = (PendingIntentRecord)sender;
6564            try {
6565                int uid = AppGlobals.getPackageManager()
6566                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
6567                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6568                    String msg = "Permission Denial: cancelIntentSender() from pid="
6569                        + Binder.getCallingPid()
6570                        + ", uid=" + Binder.getCallingUid()
6571                        + " is not allowed to cancel packges "
6572                        + rec.key.packageName;
6573                    Slog.w(TAG, msg);
6574                    throw new SecurityException(msg);
6575                }
6576            } catch (RemoteException e) {
6577                throw new SecurityException(e);
6578            }
6579            cancelIntentSenderLocked(rec, true);
6580        }
6581    }
6582
6583    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
6584        rec.canceled = true;
6585        mIntentSenderRecords.remove(rec.key);
6586        if (cleanActivity && rec.key.activity != null) {
6587            rec.key.activity.pendingResults.remove(rec.ref);
6588        }
6589    }
6590
6591    @Override
6592    public String getPackageForIntentSender(IIntentSender pendingResult) {
6593        if (!(pendingResult instanceof PendingIntentRecord)) {
6594            return null;
6595        }
6596        try {
6597            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6598            return res.key.packageName;
6599        } catch (ClassCastException e) {
6600        }
6601        return null;
6602    }
6603
6604    @Override
6605    public int getUidForIntentSender(IIntentSender sender) {
6606        if (sender instanceof PendingIntentRecord) {
6607            try {
6608                PendingIntentRecord res = (PendingIntentRecord)sender;
6609                return res.uid;
6610            } catch (ClassCastException e) {
6611            }
6612        }
6613        return -1;
6614    }
6615
6616    @Override
6617    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
6618        if (!(pendingResult instanceof PendingIntentRecord)) {
6619            return false;
6620        }
6621        try {
6622            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6623            if (res.key.allIntents == null) {
6624                return false;
6625            }
6626            for (int i=0; i<res.key.allIntents.length; i++) {
6627                Intent intent = res.key.allIntents[i];
6628                if (intent.getPackage() != null && intent.getComponent() != null) {
6629                    return false;
6630                }
6631            }
6632            return true;
6633        } catch (ClassCastException e) {
6634        }
6635        return false;
6636    }
6637
6638    @Override
6639    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
6640        if (!(pendingResult instanceof PendingIntentRecord)) {
6641            return false;
6642        }
6643        try {
6644            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6645            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6646                return true;
6647            }
6648            return false;
6649        } catch (ClassCastException e) {
6650        }
6651        return false;
6652    }
6653
6654    @Override
6655    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6656        if (!(pendingResult instanceof PendingIntentRecord)) {
6657            return null;
6658        }
6659        try {
6660            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6661            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6662        } catch (ClassCastException e) {
6663        }
6664        return null;
6665    }
6666
6667    @Override
6668    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6669        if (!(pendingResult instanceof PendingIntentRecord)) {
6670            return null;
6671        }
6672        try {
6673            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6674            Intent intent = res.key.requestIntent;
6675            if (intent != null) {
6676                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6677                        || res.lastTagPrefix.equals(prefix))) {
6678                    return res.lastTag;
6679                }
6680                res.lastTagPrefix = prefix;
6681                StringBuilder sb = new StringBuilder(128);
6682                if (prefix != null) {
6683                    sb.append(prefix);
6684                }
6685                if (intent.getAction() != null) {
6686                    sb.append(intent.getAction());
6687                } else if (intent.getComponent() != null) {
6688                    intent.getComponent().appendShortString(sb);
6689                } else {
6690                    sb.append("?");
6691                }
6692                return res.lastTag = sb.toString();
6693            }
6694        } catch (ClassCastException e) {
6695        }
6696        return null;
6697    }
6698
6699    @Override
6700    public void setProcessLimit(int max) {
6701        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6702                "setProcessLimit()");
6703        synchronized (this) {
6704            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6705            mProcessLimitOverride = max;
6706        }
6707        trimApplications();
6708    }
6709
6710    @Override
6711    public int getProcessLimit() {
6712        synchronized (this) {
6713            return mProcessLimitOverride;
6714        }
6715    }
6716
6717    void foregroundTokenDied(ForegroundToken token) {
6718        synchronized (ActivityManagerService.this) {
6719            synchronized (mPidsSelfLocked) {
6720                ForegroundToken cur
6721                    = mForegroundProcesses.get(token.pid);
6722                if (cur != token) {
6723                    return;
6724                }
6725                mForegroundProcesses.remove(token.pid);
6726                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6727                if (pr == null) {
6728                    return;
6729                }
6730                pr.forcingToForeground = null;
6731                updateProcessForegroundLocked(pr, false, false);
6732            }
6733            updateOomAdjLocked();
6734        }
6735    }
6736
6737    @Override
6738    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6739        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6740                "setProcessForeground()");
6741        synchronized(this) {
6742            boolean changed = false;
6743
6744            synchronized (mPidsSelfLocked) {
6745                ProcessRecord pr = mPidsSelfLocked.get(pid);
6746                if (pr == null && isForeground) {
6747                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6748                    return;
6749                }
6750                ForegroundToken oldToken = mForegroundProcesses.get(pid);
6751                if (oldToken != null) {
6752                    oldToken.token.unlinkToDeath(oldToken, 0);
6753                    mForegroundProcesses.remove(pid);
6754                    if (pr != null) {
6755                        pr.forcingToForeground = null;
6756                    }
6757                    changed = true;
6758                }
6759                if (isForeground && token != null) {
6760                    ForegroundToken newToken = new ForegroundToken() {
6761                        @Override
6762                        public void binderDied() {
6763                            foregroundTokenDied(this);
6764                        }
6765                    };
6766                    newToken.pid = pid;
6767                    newToken.token = token;
6768                    try {
6769                        token.linkToDeath(newToken, 0);
6770                        mForegroundProcesses.put(pid, newToken);
6771                        pr.forcingToForeground = token;
6772                        changed = true;
6773                    } catch (RemoteException e) {
6774                        // If the process died while doing this, we will later
6775                        // do the cleanup with the process death link.
6776                    }
6777                }
6778            }
6779
6780            if (changed) {
6781                updateOomAdjLocked();
6782            }
6783        }
6784    }
6785
6786    // =========================================================
6787    // PERMISSIONS
6788    // =========================================================
6789
6790    static class PermissionController extends IPermissionController.Stub {
6791        ActivityManagerService mActivityManagerService;
6792        PermissionController(ActivityManagerService activityManagerService) {
6793            mActivityManagerService = activityManagerService;
6794        }
6795
6796        @Override
6797        public boolean checkPermission(String permission, int pid, int uid) {
6798            return mActivityManagerService.checkPermission(permission, pid,
6799                    uid) == PackageManager.PERMISSION_GRANTED;
6800        }
6801    }
6802
6803    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6804        @Override
6805        public int checkComponentPermission(String permission, int pid, int uid,
6806                int owningUid, boolean exported) {
6807            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6808                    owningUid, exported);
6809        }
6810
6811        @Override
6812        public Object getAMSLock() {
6813            return ActivityManagerService.this;
6814        }
6815    }
6816
6817    /**
6818     * This can be called with or without the global lock held.
6819     */
6820    int checkComponentPermission(String permission, int pid, int uid,
6821            int owningUid, boolean exported) {
6822        if (pid == MY_PID) {
6823            return PackageManager.PERMISSION_GRANTED;
6824        }
6825        return ActivityManager.checkComponentPermission(permission, uid,
6826                owningUid, exported);
6827    }
6828
6829    /**
6830     * As the only public entry point for permissions checking, this method
6831     * can enforce the semantic that requesting a check on a null global
6832     * permission is automatically denied.  (Internally a null permission
6833     * string is used when calling {@link #checkComponentPermission} in cases
6834     * when only uid-based security is needed.)
6835     *
6836     * This can be called with or without the global lock held.
6837     */
6838    @Override
6839    public int checkPermission(String permission, int pid, int uid) {
6840        if (permission == null) {
6841            return PackageManager.PERMISSION_DENIED;
6842        }
6843        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6844    }
6845
6846    @Override
6847    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
6848        if (permission == null) {
6849            return PackageManager.PERMISSION_DENIED;
6850        }
6851
6852        // We might be performing an operation on behalf of an indirect binder
6853        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
6854        // client identity accordingly before proceeding.
6855        Identity tlsIdentity = sCallerIdentity.get();
6856        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
6857            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6858                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6859            uid = tlsIdentity.uid;
6860            pid = tlsIdentity.pid;
6861        }
6862
6863        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6864    }
6865
6866    /**
6867     * Binder IPC calls go through the public entry point.
6868     * This can be called with or without the global lock held.
6869     */
6870    int checkCallingPermission(String permission) {
6871        return checkPermission(permission,
6872                Binder.getCallingPid(),
6873                UserHandle.getAppId(Binder.getCallingUid()));
6874    }
6875
6876    /**
6877     * This can be called with or without the global lock held.
6878     */
6879    void enforceCallingPermission(String permission, String func) {
6880        if (checkCallingPermission(permission)
6881                == PackageManager.PERMISSION_GRANTED) {
6882            return;
6883        }
6884
6885        String msg = "Permission Denial: " + func + " from pid="
6886                + Binder.getCallingPid()
6887                + ", uid=" + Binder.getCallingUid()
6888                + " requires " + permission;
6889        Slog.w(TAG, msg);
6890        throw new SecurityException(msg);
6891    }
6892
6893    /**
6894     * Determine if UID is holding permissions required to access {@link Uri} in
6895     * the given {@link ProviderInfo}. Final permission checking is always done
6896     * in {@link ContentProvider}.
6897     */
6898    private final boolean checkHoldingPermissionsLocked(
6899            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
6900        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6901                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
6902        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
6903            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
6904                    != PERMISSION_GRANTED) {
6905                return false;
6906            }
6907        }
6908        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
6909    }
6910
6911    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
6912            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
6913        if (pi.applicationInfo.uid == uid) {
6914            return true;
6915        } else if (!pi.exported) {
6916            return false;
6917        }
6918
6919        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6920        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6921        try {
6922            // check if target holds top-level <provider> permissions
6923            if (!readMet && pi.readPermission != null && considerUidPermissions
6924                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6925                readMet = true;
6926            }
6927            if (!writeMet && pi.writePermission != null && considerUidPermissions
6928                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6929                writeMet = true;
6930            }
6931
6932            // track if unprotected read/write is allowed; any denied
6933            // <path-permission> below removes this ability
6934            boolean allowDefaultRead = pi.readPermission == null;
6935            boolean allowDefaultWrite = pi.writePermission == null;
6936
6937            // check if target holds any <path-permission> that match uri
6938            final PathPermission[] pps = pi.pathPermissions;
6939            if (pps != null) {
6940                final String path = grantUri.uri.getPath();
6941                int i = pps.length;
6942                while (i > 0 && (!readMet || !writeMet)) {
6943                    i--;
6944                    PathPermission pp = pps[i];
6945                    if (pp.match(path)) {
6946                        if (!readMet) {
6947                            final String pprperm = pp.getReadPermission();
6948                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
6949                                    + pprperm + " for " + pp.getPath()
6950                                    + ": match=" + pp.match(path)
6951                                    + " check=" + pm.checkUidPermission(pprperm, uid));
6952                            if (pprperm != null) {
6953                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
6954                                        == PERMISSION_GRANTED) {
6955                                    readMet = true;
6956                                } else {
6957                                    allowDefaultRead = false;
6958                                }
6959                            }
6960                        }
6961                        if (!writeMet) {
6962                            final String ppwperm = pp.getWritePermission();
6963                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
6964                                    + ppwperm + " for " + pp.getPath()
6965                                    + ": match=" + pp.match(path)
6966                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
6967                            if (ppwperm != null) {
6968                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
6969                                        == PERMISSION_GRANTED) {
6970                                    writeMet = true;
6971                                } else {
6972                                    allowDefaultWrite = false;
6973                                }
6974                            }
6975                        }
6976                    }
6977                }
6978            }
6979
6980            // grant unprotected <provider> read/write, if not blocked by
6981            // <path-permission> above
6982            if (allowDefaultRead) readMet = true;
6983            if (allowDefaultWrite) writeMet = true;
6984
6985        } catch (RemoteException e) {
6986            return false;
6987        }
6988
6989        return readMet && writeMet;
6990    }
6991
6992    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
6993        ProviderInfo pi = null;
6994        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
6995        if (cpr != null) {
6996            pi = cpr.info;
6997        } else {
6998            try {
6999                pi = AppGlobals.getPackageManager().resolveContentProvider(
7000                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
7001            } catch (RemoteException ex) {
7002            }
7003        }
7004        return pi;
7005    }
7006
7007    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7008        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7009        if (targetUris != null) {
7010            return targetUris.get(grantUri);
7011        }
7012        return null;
7013    }
7014
7015    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7016            String targetPkg, int targetUid, GrantUri grantUri) {
7017        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7018        if (targetUris == null) {
7019            targetUris = Maps.newArrayMap();
7020            mGrantedUriPermissions.put(targetUid, targetUris);
7021        }
7022
7023        UriPermission perm = targetUris.get(grantUri);
7024        if (perm == null) {
7025            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7026            targetUris.put(grantUri, perm);
7027        }
7028
7029        return perm;
7030    }
7031
7032    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7033            final int modeFlags) {
7034        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7035        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7036                : UriPermission.STRENGTH_OWNED;
7037
7038        // Root gets to do everything.
7039        if (uid == 0) {
7040            return true;
7041        }
7042
7043        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7044        if (perms == null) return false;
7045
7046        // First look for exact match
7047        final UriPermission exactPerm = perms.get(grantUri);
7048        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7049            return true;
7050        }
7051
7052        // No exact match, look for prefixes
7053        final int N = perms.size();
7054        for (int i = 0; i < N; i++) {
7055            final UriPermission perm = perms.valueAt(i);
7056            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7057                    && perm.getStrength(modeFlags) >= minStrength) {
7058                return true;
7059            }
7060        }
7061
7062        return false;
7063    }
7064
7065    /**
7066     * @param uri This uri must NOT contain an embedded userId.
7067     * @param userId The userId in which the uri is to be resolved.
7068     */
7069    @Override
7070    public int checkUriPermission(Uri uri, int pid, int uid,
7071            final int modeFlags, int userId, IBinder callerToken) {
7072        enforceNotIsolatedCaller("checkUriPermission");
7073
7074        // Another redirected-binder-call permissions check as in
7075        // {@link checkPermissionWithToken}.
7076        Identity tlsIdentity = sCallerIdentity.get();
7077        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7078            uid = tlsIdentity.uid;
7079            pid = tlsIdentity.pid;
7080        }
7081
7082        // Our own process gets to do everything.
7083        if (pid == MY_PID) {
7084            return PackageManager.PERMISSION_GRANTED;
7085        }
7086        synchronized (this) {
7087            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7088                    ? PackageManager.PERMISSION_GRANTED
7089                    : PackageManager.PERMISSION_DENIED;
7090        }
7091    }
7092
7093    /**
7094     * Check if the targetPkg can be granted permission to access uri by
7095     * the callingUid using the given modeFlags.  Throws a security exception
7096     * if callingUid is not allowed to do this.  Returns the uid of the target
7097     * if the URI permission grant should be performed; returns -1 if it is not
7098     * needed (for example targetPkg already has permission to access the URI).
7099     * If you already know the uid of the target, you can supply it in
7100     * lastTargetUid else set that to -1.
7101     */
7102    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7103            final int modeFlags, int lastTargetUid) {
7104        if (!Intent.isAccessUriMode(modeFlags)) {
7105            return -1;
7106        }
7107
7108        if (targetPkg != null) {
7109            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7110                    "Checking grant " + targetPkg + " permission to " + grantUri);
7111        }
7112
7113        final IPackageManager pm = AppGlobals.getPackageManager();
7114
7115        // If this is not a content: uri, we can't do anything with it.
7116        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7117            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7118                    "Can't grant URI permission for non-content URI: " + grantUri);
7119            return -1;
7120        }
7121
7122        final String authority = grantUri.uri.getAuthority();
7123        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7124        if (pi == null) {
7125            Slog.w(TAG, "No content provider found for permission check: " +
7126                    grantUri.uri.toSafeString());
7127            return -1;
7128        }
7129
7130        int targetUid = lastTargetUid;
7131        if (targetUid < 0 && targetPkg != null) {
7132            try {
7133                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
7134                if (targetUid < 0) {
7135                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7136                            "Can't grant URI permission no uid for: " + targetPkg);
7137                    return -1;
7138                }
7139            } catch (RemoteException ex) {
7140                return -1;
7141            }
7142        }
7143
7144        if (targetUid >= 0) {
7145            // First...  does the target actually need this permission?
7146            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7147                // No need to grant the target this permission.
7148                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7149                        "Target " + targetPkg + " already has full permission to " + grantUri);
7150                return -1;
7151            }
7152        } else {
7153            // First...  there is no target package, so can anyone access it?
7154            boolean allowed = pi.exported;
7155            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7156                if (pi.readPermission != null) {
7157                    allowed = false;
7158                }
7159            }
7160            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7161                if (pi.writePermission != null) {
7162                    allowed = false;
7163                }
7164            }
7165            if (allowed) {
7166                return -1;
7167            }
7168        }
7169
7170        /* There is a special cross user grant if:
7171         * - The target is on another user.
7172         * - Apps on the current user can access the uri without any uid permissions.
7173         * In this case, we grant a uri permission, even if the ContentProvider does not normally
7174         * grant uri permissions.
7175         */
7176        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7177                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7178                modeFlags, false /*without considering the uid permissions*/);
7179
7180        // Second...  is the provider allowing granting of URI permissions?
7181        if (!specialCrossUserGrant) {
7182            if (!pi.grantUriPermissions) {
7183                throw new SecurityException("Provider " + pi.packageName
7184                        + "/" + pi.name
7185                        + " does not allow granting of Uri permissions (uri "
7186                        + grantUri + ")");
7187            }
7188            if (pi.uriPermissionPatterns != null) {
7189                final int N = pi.uriPermissionPatterns.length;
7190                boolean allowed = false;
7191                for (int i=0; i<N; i++) {
7192                    if (pi.uriPermissionPatterns[i] != null
7193                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7194                        allowed = true;
7195                        break;
7196                    }
7197                }
7198                if (!allowed) {
7199                    throw new SecurityException("Provider " + pi.packageName
7200                            + "/" + pi.name
7201                            + " does not allow granting of permission to path of Uri "
7202                            + grantUri);
7203                }
7204            }
7205        }
7206
7207        // Third...  does the caller itself have permission to access
7208        // this uri?
7209        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
7210            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7211                // Require they hold a strong enough Uri permission
7212                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7213                    throw new SecurityException("Uid " + callingUid
7214                            + " does not have permission to uri " + grantUri);
7215                }
7216            }
7217        }
7218        return targetUid;
7219    }
7220
7221    /**
7222     * @param uri This uri must NOT contain an embedded userId.
7223     * @param userId The userId in which the uri is to be resolved.
7224     */
7225    @Override
7226    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
7227            final int modeFlags, int userId) {
7228        enforceNotIsolatedCaller("checkGrantUriPermission");
7229        synchronized(this) {
7230            return checkGrantUriPermissionLocked(callingUid, targetPkg,
7231                    new GrantUri(userId, uri, false), modeFlags, -1);
7232        }
7233    }
7234
7235    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
7236            final int modeFlags, UriPermissionOwner owner) {
7237        if (!Intent.isAccessUriMode(modeFlags)) {
7238            return;
7239        }
7240
7241        // So here we are: the caller has the assumed permission
7242        // to the uri, and the target doesn't.  Let's now give this to
7243        // the target.
7244
7245        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7246                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
7247
7248        final String authority = grantUri.uri.getAuthority();
7249        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7250        if (pi == null) {
7251            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
7252            return;
7253        }
7254
7255        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
7256            grantUri.prefix = true;
7257        }
7258        final UriPermission perm = findOrCreateUriPermissionLocked(
7259                pi.packageName, targetPkg, targetUid, grantUri);
7260        perm.grantModes(modeFlags, owner);
7261    }
7262
7263    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7264            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
7265        if (targetPkg == null) {
7266            throw new NullPointerException("targetPkg");
7267        }
7268        int targetUid;
7269        final IPackageManager pm = AppGlobals.getPackageManager();
7270        try {
7271            targetUid = pm.getPackageUid(targetPkg, targetUserId);
7272        } catch (RemoteException ex) {
7273            return;
7274        }
7275
7276        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
7277                targetUid);
7278        if (targetUid < 0) {
7279            return;
7280        }
7281
7282        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
7283                owner);
7284    }
7285
7286    static class NeededUriGrants extends ArrayList<GrantUri> {
7287        final String targetPkg;
7288        final int targetUid;
7289        final int flags;
7290
7291        NeededUriGrants(String targetPkg, int targetUid, int flags) {
7292            this.targetPkg = targetPkg;
7293            this.targetUid = targetUid;
7294            this.flags = flags;
7295        }
7296    }
7297
7298    /**
7299     * Like checkGrantUriPermissionLocked, but takes an Intent.
7300     */
7301    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
7302            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
7303        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7304                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
7305                + " clip=" + (intent != null ? intent.getClipData() : null)
7306                + " from " + intent + "; flags=0x"
7307                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
7308
7309        if (targetPkg == null) {
7310            throw new NullPointerException("targetPkg");
7311        }
7312
7313        if (intent == null) {
7314            return null;
7315        }
7316        Uri data = intent.getData();
7317        ClipData clip = intent.getClipData();
7318        if (data == null && clip == null) {
7319            return null;
7320        }
7321        // Default userId for uris in the intent (if they don't specify it themselves)
7322        int contentUserHint = intent.getContentUserHint();
7323        if (contentUserHint == UserHandle.USER_CURRENT) {
7324            contentUserHint = UserHandle.getUserId(callingUid);
7325        }
7326        final IPackageManager pm = AppGlobals.getPackageManager();
7327        int targetUid;
7328        if (needed != null) {
7329            targetUid = needed.targetUid;
7330        } else {
7331            try {
7332                targetUid = pm.getPackageUid(targetPkg, targetUserId);
7333            } catch (RemoteException ex) {
7334                return null;
7335            }
7336            if (targetUid < 0) {
7337                if (DEBUG_URI_PERMISSION) {
7338                    Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
7339                            + " on user " + targetUserId);
7340                }
7341                return null;
7342            }
7343        }
7344        if (data != null) {
7345            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
7346            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7347                    targetUid);
7348            if (targetUid > 0) {
7349                if (needed == null) {
7350                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
7351                }
7352                needed.add(grantUri);
7353            }
7354        }
7355        if (clip != null) {
7356            for (int i=0; i<clip.getItemCount(); i++) {
7357                Uri uri = clip.getItemAt(i).getUri();
7358                if (uri != null) {
7359                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
7360                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7361                            targetUid);
7362                    if (targetUid > 0) {
7363                        if (needed == null) {
7364                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
7365                        }
7366                        needed.add(grantUri);
7367                    }
7368                } else {
7369                    Intent clipIntent = clip.getItemAt(i).getIntent();
7370                    if (clipIntent != null) {
7371                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
7372                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
7373                        if (newNeeded != null) {
7374                            needed = newNeeded;
7375                        }
7376                    }
7377                }
7378            }
7379        }
7380
7381        return needed;
7382    }
7383
7384    /**
7385     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
7386     */
7387    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
7388            UriPermissionOwner owner) {
7389        if (needed != null) {
7390            for (int i=0; i<needed.size(); i++) {
7391                GrantUri grantUri = needed.get(i);
7392                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
7393                        grantUri, needed.flags, owner);
7394            }
7395        }
7396    }
7397
7398    void grantUriPermissionFromIntentLocked(int callingUid,
7399            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
7400        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
7401                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
7402        if (needed == null) {
7403            return;
7404        }
7405
7406        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
7407    }
7408
7409    /**
7410     * @param uri This uri must NOT contain an embedded userId.
7411     * @param userId The userId in which the uri is to be resolved.
7412     */
7413    @Override
7414    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
7415            final int modeFlags, int userId) {
7416        enforceNotIsolatedCaller("grantUriPermission");
7417        GrantUri grantUri = new GrantUri(userId, uri, false);
7418        synchronized(this) {
7419            final ProcessRecord r = getRecordForAppLocked(caller);
7420            if (r == null) {
7421                throw new SecurityException("Unable to find app for caller "
7422                        + caller
7423                        + " when granting permission to uri " + grantUri);
7424            }
7425            if (targetPkg == null) {
7426                throw new IllegalArgumentException("null target");
7427            }
7428            if (grantUri == null) {
7429                throw new IllegalArgumentException("null uri");
7430            }
7431
7432            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
7433                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
7434                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
7435                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
7436
7437            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
7438                    UserHandle.getUserId(r.uid));
7439        }
7440    }
7441
7442    void removeUriPermissionIfNeededLocked(UriPermission perm) {
7443        if (perm.modeFlags == 0) {
7444            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7445                    perm.targetUid);
7446            if (perms != null) {
7447                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7448                        "Removing " + perm.targetUid + " permission to " + perm.uri);
7449
7450                perms.remove(perm.uri);
7451                if (perms.isEmpty()) {
7452                    mGrantedUriPermissions.remove(perm.targetUid);
7453                }
7454            }
7455        }
7456    }
7457
7458    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
7459        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
7460
7461        final IPackageManager pm = AppGlobals.getPackageManager();
7462        final String authority = grantUri.uri.getAuthority();
7463        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7464        if (pi == null) {
7465            Slog.w(TAG, "No content provider found for permission revoke: "
7466                    + grantUri.toSafeString());
7467            return;
7468        }
7469
7470        // Does the caller have this permission on the URI?
7471        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7472            // If they don't have direct access to the URI, then revoke any
7473            // ownerless URI permissions that have been granted to them.
7474            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7475            if (perms != null) {
7476                boolean persistChanged = false;
7477                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7478                    final UriPermission perm = it.next();
7479                    if (perm.uri.sourceUserId == grantUri.sourceUserId
7480                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7481                        if (DEBUG_URI_PERMISSION)
7482                            Slog.v(TAG, "Revoking non-owned " + perm.targetUid +
7483                                    " permission to " + perm.uri);
7484                        persistChanged |= perm.revokeModes(
7485                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
7486                        if (perm.modeFlags == 0) {
7487                            it.remove();
7488                        }
7489                    }
7490                }
7491                if (perms.isEmpty()) {
7492                    mGrantedUriPermissions.remove(callingUid);
7493                }
7494                if (persistChanged) {
7495                    schedulePersistUriGrants();
7496                }
7497            }
7498            return;
7499        }
7500
7501        boolean persistChanged = false;
7502
7503        // Go through all of the permissions and remove any that match.
7504        int N = mGrantedUriPermissions.size();
7505        for (int i = 0; i < N; i++) {
7506            final int targetUid = mGrantedUriPermissions.keyAt(i);
7507            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7508
7509            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7510                final UriPermission perm = it.next();
7511                if (perm.uri.sourceUserId == grantUri.sourceUserId
7512                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7513                    if (DEBUG_URI_PERMISSION)
7514                        Slog.v(TAG,
7515                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
7516                    persistChanged |= perm.revokeModes(
7517                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7518                    if (perm.modeFlags == 0) {
7519                        it.remove();
7520                    }
7521                }
7522            }
7523
7524            if (perms.isEmpty()) {
7525                mGrantedUriPermissions.remove(targetUid);
7526                N--;
7527                i--;
7528            }
7529        }
7530
7531        if (persistChanged) {
7532            schedulePersistUriGrants();
7533        }
7534    }
7535
7536    /**
7537     * @param uri This uri must NOT contain an embedded userId.
7538     * @param userId The userId in which the uri is to be resolved.
7539     */
7540    @Override
7541    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
7542            int userId) {
7543        enforceNotIsolatedCaller("revokeUriPermission");
7544        synchronized(this) {
7545            final ProcessRecord r = getRecordForAppLocked(caller);
7546            if (r == null) {
7547                throw new SecurityException("Unable to find app for caller "
7548                        + caller
7549                        + " when revoking permission to uri " + uri);
7550            }
7551            if (uri == null) {
7552                Slog.w(TAG, "revokeUriPermission: null uri");
7553                return;
7554            }
7555
7556            if (!Intent.isAccessUriMode(modeFlags)) {
7557                return;
7558            }
7559
7560            final IPackageManager pm = AppGlobals.getPackageManager();
7561            final String authority = uri.getAuthority();
7562            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
7563            if (pi == null) {
7564                Slog.w(TAG, "No content provider found for permission revoke: "
7565                        + uri.toSafeString());
7566                return;
7567            }
7568
7569            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
7570        }
7571    }
7572
7573    /**
7574     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
7575     * given package.
7576     *
7577     * @param packageName Package name to match, or {@code null} to apply to all
7578     *            packages.
7579     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
7580     *            to all users.
7581     * @param persistable If persistable grants should be removed.
7582     */
7583    private void removeUriPermissionsForPackageLocked(
7584            String packageName, int userHandle, boolean persistable) {
7585        if (userHandle == UserHandle.USER_ALL && packageName == null) {
7586            throw new IllegalArgumentException("Must narrow by either package or user");
7587        }
7588
7589        boolean persistChanged = false;
7590
7591        int N = mGrantedUriPermissions.size();
7592        for (int i = 0; i < N; i++) {
7593            final int targetUid = mGrantedUriPermissions.keyAt(i);
7594            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7595
7596            // Only inspect grants matching user
7597            if (userHandle == UserHandle.USER_ALL
7598                    || userHandle == UserHandle.getUserId(targetUid)) {
7599                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7600                    final UriPermission perm = it.next();
7601
7602                    // Only inspect grants matching package
7603                    if (packageName == null || perm.sourcePkg.equals(packageName)
7604                            || perm.targetPkg.equals(packageName)) {
7605                        persistChanged |= perm.revokeModes(persistable
7606                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7607
7608                        // Only remove when no modes remain; any persisted grants
7609                        // will keep this alive.
7610                        if (perm.modeFlags == 0) {
7611                            it.remove();
7612                        }
7613                    }
7614                }
7615
7616                if (perms.isEmpty()) {
7617                    mGrantedUriPermissions.remove(targetUid);
7618                    N--;
7619                    i--;
7620                }
7621            }
7622        }
7623
7624        if (persistChanged) {
7625            schedulePersistUriGrants();
7626        }
7627    }
7628
7629    @Override
7630    public IBinder newUriPermissionOwner(String name) {
7631        enforceNotIsolatedCaller("newUriPermissionOwner");
7632        synchronized(this) {
7633            UriPermissionOwner owner = new UriPermissionOwner(this, name);
7634            return owner.getExternalTokenLocked();
7635        }
7636    }
7637
7638    /**
7639     * @param uri This uri must NOT contain an embedded userId.
7640     * @param sourceUserId The userId in which the uri is to be resolved.
7641     * @param targetUserId The userId of the app that receives the grant.
7642     */
7643    @Override
7644    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
7645            final int modeFlags, int sourceUserId, int targetUserId) {
7646        targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
7647                targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null);
7648        synchronized(this) {
7649            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7650            if (owner == null) {
7651                throw new IllegalArgumentException("Unknown owner: " + token);
7652            }
7653            if (fromUid != Binder.getCallingUid()) {
7654                if (Binder.getCallingUid() != Process.myUid()) {
7655                    // Only system code can grant URI permissions on behalf
7656                    // of other users.
7657                    throw new SecurityException("nice try");
7658                }
7659            }
7660            if (targetPkg == null) {
7661                throw new IllegalArgumentException("null target");
7662            }
7663            if (uri == null) {
7664                throw new IllegalArgumentException("null uri");
7665            }
7666
7667            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
7668                    modeFlags, owner, targetUserId);
7669        }
7670    }
7671
7672    /**
7673     * @param uri This uri must NOT contain an embedded userId.
7674     * @param userId The userId in which the uri is to be resolved.
7675     */
7676    @Override
7677    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
7678        synchronized(this) {
7679            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7680            if (owner == null) {
7681                throw new IllegalArgumentException("Unknown owner: " + token);
7682            }
7683
7684            if (uri == null) {
7685                owner.removeUriPermissionsLocked(mode);
7686            } else {
7687                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
7688            }
7689        }
7690    }
7691
7692    private void schedulePersistUriGrants() {
7693        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
7694            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
7695                    10 * DateUtils.SECOND_IN_MILLIS);
7696        }
7697    }
7698
7699    private void writeGrantedUriPermissions() {
7700        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
7701
7702        // Snapshot permissions so we can persist without lock
7703        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
7704        synchronized (this) {
7705            final int size = mGrantedUriPermissions.size();
7706            for (int i = 0; i < size; i++) {
7707                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7708                for (UriPermission perm : perms.values()) {
7709                    if (perm.persistedModeFlags != 0) {
7710                        persist.add(perm.snapshot());
7711                    }
7712                }
7713            }
7714        }
7715
7716        FileOutputStream fos = null;
7717        try {
7718            fos = mGrantFile.startWrite();
7719
7720            XmlSerializer out = new FastXmlSerializer();
7721            out.setOutput(fos, "utf-8");
7722            out.startDocument(null, true);
7723            out.startTag(null, TAG_URI_GRANTS);
7724            for (UriPermission.Snapshot perm : persist) {
7725                out.startTag(null, TAG_URI_GRANT);
7726                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
7727                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
7728                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
7729                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
7730                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
7731                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
7732                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
7733                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
7734                out.endTag(null, TAG_URI_GRANT);
7735            }
7736            out.endTag(null, TAG_URI_GRANTS);
7737            out.endDocument();
7738
7739            mGrantFile.finishWrite(fos);
7740        } catch (IOException e) {
7741            if (fos != null) {
7742                mGrantFile.failWrite(fos);
7743            }
7744        }
7745    }
7746
7747    private void readGrantedUriPermissionsLocked() {
7748        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
7749
7750        final long now = System.currentTimeMillis();
7751
7752        FileInputStream fis = null;
7753        try {
7754            fis = mGrantFile.openRead();
7755            final XmlPullParser in = Xml.newPullParser();
7756            in.setInput(fis, null);
7757
7758            int type;
7759            while ((type = in.next()) != END_DOCUMENT) {
7760                final String tag = in.getName();
7761                if (type == START_TAG) {
7762                    if (TAG_URI_GRANT.equals(tag)) {
7763                        final int sourceUserId;
7764                        final int targetUserId;
7765                        final int userHandle = readIntAttribute(in,
7766                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
7767                        if (userHandle != UserHandle.USER_NULL) {
7768                            // For backwards compatibility.
7769                            sourceUserId = userHandle;
7770                            targetUserId = userHandle;
7771                        } else {
7772                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
7773                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
7774                        }
7775                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
7776                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
7777                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
7778                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
7779                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
7780                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
7781
7782                        // Sanity check that provider still belongs to source package
7783                        final ProviderInfo pi = getProviderInfoLocked(
7784                                uri.getAuthority(), sourceUserId);
7785                        if (pi != null && sourcePkg.equals(pi.packageName)) {
7786                            int targetUid = -1;
7787                            try {
7788                                targetUid = AppGlobals.getPackageManager()
7789                                        .getPackageUid(targetPkg, targetUserId);
7790                            } catch (RemoteException e) {
7791                            }
7792                            if (targetUid != -1) {
7793                                final UriPermission perm = findOrCreateUriPermissionLocked(
7794                                        sourcePkg, targetPkg, targetUid,
7795                                        new GrantUri(sourceUserId, uri, prefix));
7796                                perm.initPersistedModes(modeFlags, createdTime);
7797                            }
7798                        } else {
7799                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
7800                                    + " but instead found " + pi);
7801                        }
7802                    }
7803                }
7804            }
7805        } catch (FileNotFoundException e) {
7806            // Missing grants is okay
7807        } catch (IOException e) {
7808            Slog.wtf(TAG, "Failed reading Uri grants", e);
7809        } catch (XmlPullParserException e) {
7810            Slog.wtf(TAG, "Failed reading Uri grants", e);
7811        } finally {
7812            IoUtils.closeQuietly(fis);
7813        }
7814    }
7815
7816    /**
7817     * @param uri This uri must NOT contain an embedded userId.
7818     * @param userId The userId in which the uri is to be resolved.
7819     */
7820    @Override
7821    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7822        enforceNotIsolatedCaller("takePersistableUriPermission");
7823
7824        Preconditions.checkFlagsArgument(modeFlags,
7825                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7826
7827        synchronized (this) {
7828            final int callingUid = Binder.getCallingUid();
7829            boolean persistChanged = false;
7830            GrantUri grantUri = new GrantUri(userId, uri, false);
7831
7832            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7833                    new GrantUri(userId, uri, false));
7834            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7835                    new GrantUri(userId, uri, true));
7836
7837            final boolean exactValid = (exactPerm != null)
7838                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
7839            final boolean prefixValid = (prefixPerm != null)
7840                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
7841
7842            if (!(exactValid || prefixValid)) {
7843                throw new SecurityException("No persistable permission grants found for UID "
7844                        + callingUid + " and Uri " + grantUri.toSafeString());
7845            }
7846
7847            if (exactValid) {
7848                persistChanged |= exactPerm.takePersistableModes(modeFlags);
7849            }
7850            if (prefixValid) {
7851                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
7852            }
7853
7854            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
7855
7856            if (persistChanged) {
7857                schedulePersistUriGrants();
7858            }
7859        }
7860    }
7861
7862    /**
7863     * @param uri This uri must NOT contain an embedded userId.
7864     * @param userId The userId in which the uri is to be resolved.
7865     */
7866    @Override
7867    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7868        enforceNotIsolatedCaller("releasePersistableUriPermission");
7869
7870        Preconditions.checkFlagsArgument(modeFlags,
7871                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7872
7873        synchronized (this) {
7874            final int callingUid = Binder.getCallingUid();
7875            boolean persistChanged = false;
7876
7877            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7878                    new GrantUri(userId, uri, false));
7879            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7880                    new GrantUri(userId, uri, true));
7881            if (exactPerm == null && prefixPerm == null) {
7882                throw new SecurityException("No permission grants found for UID " + callingUid
7883                        + " and Uri " + uri.toSafeString());
7884            }
7885
7886            if (exactPerm != null) {
7887                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
7888                removeUriPermissionIfNeededLocked(exactPerm);
7889            }
7890            if (prefixPerm != null) {
7891                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
7892                removeUriPermissionIfNeededLocked(prefixPerm);
7893            }
7894
7895            if (persistChanged) {
7896                schedulePersistUriGrants();
7897            }
7898        }
7899    }
7900
7901    /**
7902     * Prune any older {@link UriPermission} for the given UID until outstanding
7903     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
7904     *
7905     * @return if any mutations occured that require persisting.
7906     */
7907    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
7908        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7909        if (perms == null) return false;
7910        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
7911
7912        final ArrayList<UriPermission> persisted = Lists.newArrayList();
7913        for (UriPermission perm : perms.values()) {
7914            if (perm.persistedModeFlags != 0) {
7915                persisted.add(perm);
7916            }
7917        }
7918
7919        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
7920        if (trimCount <= 0) return false;
7921
7922        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
7923        for (int i = 0; i < trimCount; i++) {
7924            final UriPermission perm = persisted.get(i);
7925
7926            if (DEBUG_URI_PERMISSION) {
7927                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
7928            }
7929
7930            perm.releasePersistableModes(~0);
7931            removeUriPermissionIfNeededLocked(perm);
7932        }
7933
7934        return true;
7935    }
7936
7937    @Override
7938    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
7939            String packageName, boolean incoming) {
7940        enforceNotIsolatedCaller("getPersistedUriPermissions");
7941        Preconditions.checkNotNull(packageName, "packageName");
7942
7943        final int callingUid = Binder.getCallingUid();
7944        final IPackageManager pm = AppGlobals.getPackageManager();
7945        try {
7946            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
7947            if (packageUid != callingUid) {
7948                throw new SecurityException(
7949                        "Package " + packageName + " does not belong to calling UID " + callingUid);
7950            }
7951        } catch (RemoteException e) {
7952            throw new SecurityException("Failed to verify package name ownership");
7953        }
7954
7955        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
7956        synchronized (this) {
7957            if (incoming) {
7958                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7959                        callingUid);
7960                if (perms == null) {
7961                    Slog.w(TAG, "No permission grants found for " + packageName);
7962                } else {
7963                    for (UriPermission perm : perms.values()) {
7964                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
7965                            result.add(perm.buildPersistedPublicApiObject());
7966                        }
7967                    }
7968                }
7969            } else {
7970                final int size = mGrantedUriPermissions.size();
7971                for (int i = 0; i < size; i++) {
7972                    final ArrayMap<GrantUri, UriPermission> perms =
7973                            mGrantedUriPermissions.valueAt(i);
7974                    for (UriPermission perm : perms.values()) {
7975                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
7976                            result.add(perm.buildPersistedPublicApiObject());
7977                        }
7978                    }
7979                }
7980            }
7981        }
7982        return new ParceledListSlice<android.content.UriPermission>(result);
7983    }
7984
7985    @Override
7986    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
7987        synchronized (this) {
7988            ProcessRecord app =
7989                who != null ? getRecordForAppLocked(who) : null;
7990            if (app == null) return;
7991
7992            Message msg = Message.obtain();
7993            msg.what = WAIT_FOR_DEBUGGER_MSG;
7994            msg.obj = app;
7995            msg.arg1 = waiting ? 1 : 0;
7996            mHandler.sendMessage(msg);
7997        }
7998    }
7999
8000    @Override
8001    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
8002        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
8003        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
8004        outInfo.availMem = Process.getFreeMemory();
8005        outInfo.totalMem = Process.getTotalMemory();
8006        outInfo.threshold = homeAppMem;
8007        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
8008        outInfo.hiddenAppThreshold = cachedAppMem;
8009        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
8010                ProcessList.SERVICE_ADJ);
8011        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
8012                ProcessList.VISIBLE_APP_ADJ);
8013        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
8014                ProcessList.FOREGROUND_APP_ADJ);
8015    }
8016
8017    // =========================================================
8018    // TASK MANAGEMENT
8019    // =========================================================
8020
8021    @Override
8022    public List<IAppTask> getAppTasks(String callingPackage) {
8023        int callingUid = Binder.getCallingUid();
8024        long ident = Binder.clearCallingIdentity();
8025
8026        synchronized(this) {
8027            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
8028            try {
8029                if (localLOGV) Slog.v(TAG, "getAppTasks");
8030
8031                final int N = mRecentTasks.size();
8032                for (int i = 0; i < N; i++) {
8033                    TaskRecord tr = mRecentTasks.get(i);
8034                    // Skip tasks that do not match the caller.  We don't need to verify
8035                    // callingPackage, because we are also limiting to callingUid and know
8036                    // that will limit to the correct security sandbox.
8037                    if (tr.effectiveUid != callingUid) {
8038                        continue;
8039                    }
8040                    Intent intent = tr.getBaseIntent();
8041                    if (intent == null ||
8042                            !callingPackage.equals(intent.getComponent().getPackageName())) {
8043                        continue;
8044                    }
8045                    ActivityManager.RecentTaskInfo taskInfo =
8046                            createRecentTaskInfoFromTaskRecord(tr);
8047                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8048                    list.add(taskImpl);
8049                }
8050            } finally {
8051                Binder.restoreCallingIdentity(ident);
8052            }
8053            return list;
8054        }
8055    }
8056
8057    @Override
8058    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8059        final int callingUid = Binder.getCallingUid();
8060        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8061
8062        synchronized(this) {
8063            if (localLOGV) Slog.v(
8064                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8065
8066            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
8067                    callingUid);
8068
8069            // TODO: Improve with MRU list from all ActivityStacks.
8070            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8071        }
8072
8073        return list;
8074    }
8075
8076    /**
8077     * Creates a new RecentTaskInfo from a TaskRecord.
8078     */
8079    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8080        // Update the task description to reflect any changes in the task stack
8081        tr.updateTaskDescription();
8082
8083        // Compose the recent task info
8084        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8085        rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
8086        rti.persistentId = tr.taskId;
8087        rti.baseIntent = new Intent(tr.getBaseIntent());
8088        rti.origActivity = tr.origActivity;
8089        rti.description = tr.lastDescription;
8090        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8091        rti.userId = tr.userId;
8092        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8093        rti.firstActiveTime = tr.firstActiveTime;
8094        rti.lastActiveTime = tr.lastActiveTime;
8095        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8096        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8097        return rti;
8098    }
8099
8100    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
8101        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
8102                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
8103        if (!allowed) {
8104            if (checkPermission(android.Manifest.permission.GET_TASKS,
8105                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
8106                // Temporary compatibility: some existing apps on the system image may
8107                // still be requesting the old permission and not switched to the new
8108                // one; if so, we'll still allow them full access.  This means we need
8109                // to see if they are holding the old permission and are a system app.
8110                try {
8111                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
8112                        allowed = true;
8113                        Slog.w(TAG, caller + ": caller " + callingUid
8114                                + " is using old GET_TASKS but privileged; allowing");
8115                    }
8116                } catch (RemoteException e) {
8117                }
8118            }
8119        }
8120        if (!allowed) {
8121            Slog.w(TAG, caller + ": caller " + callingUid
8122                    + " does not hold GET_TASKS; limiting output");
8123        }
8124        return allowed;
8125    }
8126
8127    @Override
8128    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8129        final int callingUid = Binder.getCallingUid();
8130        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8131                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8132
8133        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8134        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8135        synchronized (this) {
8136            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
8137                    callingUid);
8138            final boolean detailed = checkCallingPermission(
8139                    android.Manifest.permission.GET_DETAILED_TASKS)
8140                    == PackageManager.PERMISSION_GRANTED;
8141
8142            final int N = mRecentTasks.size();
8143            ArrayList<ActivityManager.RecentTaskInfo> res
8144                    = new ArrayList<ActivityManager.RecentTaskInfo>(
8145                            maxNum < N ? maxNum : N);
8146
8147            final Set<Integer> includedUsers;
8148            if (includeProfiles) {
8149                includedUsers = getProfileIdsLocked(userId);
8150            } else {
8151                includedUsers = new HashSet<Integer>();
8152            }
8153            includedUsers.add(Integer.valueOf(userId));
8154
8155            for (int i=0; i<N && maxNum > 0; i++) {
8156                TaskRecord tr = mRecentTasks.get(i);
8157                // Only add calling user or related users recent tasks
8158                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
8159                    if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr);
8160                    continue;
8161                }
8162
8163                // Return the entry if desired by the caller.  We always return
8164                // the first entry, because callers always expect this to be the
8165                // foreground app.  We may filter others if the caller has
8166                // not supplied RECENT_WITH_EXCLUDED and there is some reason
8167                // we should exclude the entry.
8168
8169                if (i == 0
8170                        || withExcluded
8171                        || (tr.intent == null)
8172                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
8173                                == 0)) {
8174                    if (!allowed) {
8175                        // If the caller doesn't have the GET_TASKS permission, then only
8176                        // allow them to see a small subset of tasks -- their own and home.
8177                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
8178                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr);
8179                            continue;
8180                        }
8181                    }
8182                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
8183                        if (tr.stack != null && tr.stack.isHomeStack()) {
8184                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr);
8185                            continue;
8186                        }
8187                    }
8188                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
8189                        // Don't include auto remove tasks that are finished or finishing.
8190                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: "
8191                                + tr);
8192                        continue;
8193                    }
8194                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
8195                            && !tr.isAvailable) {
8196                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr);
8197                        continue;
8198                    }
8199
8200                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
8201                    if (!detailed) {
8202                        rti.baseIntent.replaceExtras((Bundle)null);
8203                    }
8204
8205                    res.add(rti);
8206                    maxNum--;
8207                }
8208            }
8209            return res;
8210        }
8211    }
8212
8213    TaskRecord recentTaskForIdLocked(int id) {
8214        final int N = mRecentTasks.size();
8215            for (int i=0; i<N; i++) {
8216                TaskRecord tr = mRecentTasks.get(i);
8217                if (tr.taskId == id) {
8218                    return tr;
8219                }
8220            }
8221            return null;
8222    }
8223
8224    @Override
8225    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
8226        synchronized (this) {
8227            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
8228                    "getTaskThumbnail()");
8229            TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(id);
8230            if (tr != null) {
8231                return tr.getTaskThumbnailLocked();
8232            }
8233        }
8234        return null;
8235    }
8236
8237    @Override
8238    public int addAppTask(IBinder activityToken, Intent intent,
8239            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
8240        final int callingUid = Binder.getCallingUid();
8241        final long callingIdent = Binder.clearCallingIdentity();
8242
8243        try {
8244            synchronized (this) {
8245                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8246                if (r == null) {
8247                    throw new IllegalArgumentException("Activity does not exist; token="
8248                            + activityToken);
8249                }
8250                ComponentName comp = intent.getComponent();
8251                if (comp == null) {
8252                    throw new IllegalArgumentException("Intent " + intent
8253                            + " must specify explicit component");
8254                }
8255                if (thumbnail.getWidth() != mThumbnailWidth
8256                        || thumbnail.getHeight() != mThumbnailHeight) {
8257                    throw new IllegalArgumentException("Bad thumbnail size: got "
8258                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
8259                            + mThumbnailWidth + "x" + mThumbnailHeight);
8260                }
8261                if (intent.getSelector() != null) {
8262                    intent.setSelector(null);
8263                }
8264                if (intent.getSourceBounds() != null) {
8265                    intent.setSourceBounds(null);
8266                }
8267                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
8268                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
8269                        // The caller has added this as an auto-remove task...  that makes no
8270                        // sense, so turn off auto-remove.
8271                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
8272                    }
8273                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
8274                    // Must be a new task.
8275                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8276                }
8277                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
8278                    mLastAddedTaskActivity = null;
8279                }
8280                ActivityInfo ainfo = mLastAddedTaskActivity;
8281                if (ainfo == null) {
8282                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
8283                            comp, 0, UserHandle.getUserId(callingUid));
8284                    if (ainfo.applicationInfo.uid != callingUid) {
8285                        throw new SecurityException(
8286                                "Can't add task for another application: target uid="
8287                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
8288                    }
8289                }
8290
8291                TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo,
8292                        intent, description);
8293
8294                int trimIdx = trimRecentsForTaskLocked(task, false);
8295                if (trimIdx >= 0) {
8296                    // If this would have caused a trim, then we'll abort because that
8297                    // means it would be added at the end of the list but then just removed.
8298                    return INVALID_TASK_ID;
8299                }
8300
8301                final int N = mRecentTasks.size();
8302                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
8303                    final TaskRecord tr = mRecentTasks.remove(N - 1);
8304                    tr.removedFromRecents();
8305                }
8306
8307                task.inRecents = true;
8308                mRecentTasks.add(task);
8309                r.task.stack.addTask(task, false, false);
8310
8311                task.setLastThumbnail(thumbnail);
8312                task.freeLastThumbnail();
8313
8314                return task.taskId;
8315            }
8316        } finally {
8317            Binder.restoreCallingIdentity(callingIdent);
8318        }
8319    }
8320
8321    @Override
8322    public Point getAppTaskThumbnailSize() {
8323        synchronized (this) {
8324            return new Point(mThumbnailWidth,  mThumbnailHeight);
8325        }
8326    }
8327
8328    @Override
8329    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
8330        synchronized (this) {
8331            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8332            if (r != null) {
8333                r.setTaskDescription(td);
8334                r.task.updateTaskDescription();
8335            }
8336        }
8337    }
8338
8339    @Override
8340    public Bitmap getTaskDescriptionIcon(String filename) {
8341        if (!FileUtils.isValidExtFilename(filename)
8342                || !filename.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
8343            throw new IllegalArgumentException("Bad filename: " + filename);
8344        }
8345        return mTaskPersister.getTaskDescriptionIcon(filename);
8346    }
8347
8348    @Override
8349    public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
8350            throws RemoteException {
8351        if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
8352                opts.getCustomInPlaceResId() == 0) {
8353            throw new IllegalArgumentException("Expected in-place ActivityOption " +
8354                    "with valid animation");
8355        }
8356        mWindowManager.prepareAppTransition(AppTransition.TRANSIT_TASK_IN_PLACE, false);
8357        mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
8358                opts.getCustomInPlaceResId());
8359        mWindowManager.executeAppTransition();
8360    }
8361
8362    private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess) {
8363        mRecentTasks.remove(tr);
8364        tr.removedFromRecents();
8365        ComponentName component = tr.getBaseIntent().getComponent();
8366        if (component == null) {
8367            Slog.w(TAG, "No component for base intent of task: " + tr);
8368            return;
8369        }
8370
8371        if (!killProcess) {
8372            return;
8373        }
8374
8375        // Determine if the process(es) for this task should be killed.
8376        final String pkg = component.getPackageName();
8377        ArrayList<ProcessRecord> procsToKill = new ArrayList<ProcessRecord>();
8378        ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
8379        for (int i = 0; i < pmap.size(); i++) {
8380
8381            SparseArray<ProcessRecord> uids = pmap.valueAt(i);
8382            for (int j = 0; j < uids.size(); j++) {
8383                ProcessRecord proc = uids.valueAt(j);
8384                if (proc.userId != tr.userId) {
8385                    // Don't kill process for a different user.
8386                    continue;
8387                }
8388                if (proc == mHomeProcess) {
8389                    // Don't kill the home process along with tasks from the same package.
8390                    continue;
8391                }
8392                if (!proc.pkgList.containsKey(pkg)) {
8393                    // Don't kill process that is not associated with this task.
8394                    continue;
8395                }
8396
8397                for (int k = 0; k < proc.activities.size(); k++) {
8398                    TaskRecord otherTask = proc.activities.get(k).task;
8399                    if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
8400                        // Don't kill process(es) that has an activity in a different task that is
8401                        // also in recents.
8402                        return;
8403                    }
8404                }
8405
8406                // Add process to kill list.
8407                procsToKill.add(proc);
8408            }
8409        }
8410
8411        // Find any running services associated with this app and stop if needed.
8412        mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
8413
8414        // Kill the running processes.
8415        for (int i = 0; i < procsToKill.size(); i++) {
8416            ProcessRecord pr = procsToKill.get(i);
8417            if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
8418                pr.kill("remove task", true);
8419            } else {
8420                pr.waitingToKill = "remove task";
8421            }
8422        }
8423    }
8424
8425    private void removeTasksByPackageNameLocked(String packageName, int userId) {
8426        // Remove all tasks with activities in the specified package from the list of recent tasks
8427        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
8428            TaskRecord tr = mRecentTasks.get(i);
8429            if (tr.userId != userId) continue;
8430
8431            ComponentName cn = tr.intent.getComponent();
8432            if (cn != null && cn.getPackageName().equals(packageName)) {
8433                // If the package name matches, remove the task.
8434                removeTaskByIdLocked(tr.taskId, true);
8435            }
8436        }
8437    }
8438
8439    private void removeTasksByRemovedPackageComponentsLocked(String packageName, int userId) {
8440        final IPackageManager pm = AppGlobals.getPackageManager();
8441        final HashSet<ComponentName> componentsKnownToExist = new HashSet<ComponentName>();
8442
8443        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
8444            TaskRecord tr = mRecentTasks.get(i);
8445            if (tr.userId != userId) continue;
8446
8447            ComponentName cn = tr.intent.getComponent();
8448            if (cn != null && cn.getPackageName().equals(packageName)) {
8449                // Skip if component still exists in the package.
8450                if (componentsKnownToExist.contains(cn)) continue;
8451
8452                try {
8453                    ActivityInfo info = pm.getActivityInfo(cn, 0, userId);
8454                    if (info != null) {
8455                        componentsKnownToExist.add(cn);
8456                    } else {
8457                        removeTaskByIdLocked(tr.taskId, false);
8458                    }
8459                } catch (RemoteException e) {
8460                    Log.e(TAG, "Activity info query failed. component=" + cn, e);
8461                }
8462            }
8463        }
8464    }
8465
8466    /**
8467     * Removes the task with the specified task id.
8468     *
8469     * @param taskId Identifier of the task to be removed.
8470     * @param killProcess Kill any process associated with the task if possible.
8471     * @return Returns true if the given task was found and removed.
8472     */
8473    private boolean removeTaskByIdLocked(int taskId, boolean killProcess) {
8474        TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(taskId);
8475        if (tr != null) {
8476            tr.removeTaskActivitiesLocked();
8477            cleanUpRemovedTaskLocked(tr, killProcess);
8478            if (tr.isPersistable) {
8479                notifyTaskPersisterLocked(null, true);
8480            }
8481            return true;
8482        }
8483        Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
8484        return false;
8485    }
8486
8487    @Override
8488    public boolean removeTask(int taskId) {
8489        synchronized (this) {
8490            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
8491                    "removeTask()");
8492            long ident = Binder.clearCallingIdentity();
8493            try {
8494                return removeTaskByIdLocked(taskId, true);
8495            } finally {
8496                Binder.restoreCallingIdentity(ident);
8497            }
8498        }
8499    }
8500
8501    /**
8502     * TODO: Add mController hook
8503     */
8504    @Override
8505    public void moveTaskToFront(int taskId, int flags, Bundle options) {
8506        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8507                "moveTaskToFront()");
8508
8509        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
8510        synchronized(this) {
8511            moveTaskToFrontLocked(taskId, flags, options);
8512        }
8513    }
8514
8515    void moveTaskToFrontLocked(int taskId, int flags, Bundle options) {
8516        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8517                Binder.getCallingUid(), -1, -1, "Task to front")) {
8518            ActivityOptions.abort(options);
8519            return;
8520        }
8521        final long origId = Binder.clearCallingIdentity();
8522        try {
8523            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8524            if (task == null) {
8525                Slog.d(TAG, "Could not find task for id: "+ taskId);
8526                return;
8527            }
8528            if (mStackSupervisor.isLockTaskModeViolation(task)) {
8529                mStackSupervisor.showLockTaskToast();
8530                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
8531                return;
8532            }
8533            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
8534            if (prev != null && prev.isRecentsActivity()) {
8535                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
8536            }
8537            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
8538        } finally {
8539            Binder.restoreCallingIdentity(origId);
8540        }
8541        ActivityOptions.abort(options);
8542    }
8543
8544    @Override
8545    public void moveTaskToBack(int taskId) {
8546        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8547                "moveTaskToBack()");
8548
8549        synchronized(this) {
8550            TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(taskId);
8551            if (tr != null) {
8552                if (tr == mStackSupervisor.mLockTaskModeTask) {
8553                    mStackSupervisor.showLockTaskToast();
8554                    return;
8555                }
8556                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
8557                ActivityStack stack = tr.stack;
8558                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
8559                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8560                            Binder.getCallingUid(), -1, -1, "Task to back")) {
8561                        return;
8562                    }
8563                }
8564                final long origId = Binder.clearCallingIdentity();
8565                try {
8566                    stack.moveTaskToBackLocked(taskId, null);
8567                } finally {
8568                    Binder.restoreCallingIdentity(origId);
8569                }
8570            }
8571        }
8572    }
8573
8574    /**
8575     * Moves an activity, and all of the other activities within the same task, to the bottom
8576     * of the history stack.  The activity's order within the task is unchanged.
8577     *
8578     * @param token A reference to the activity we wish to move
8579     * @param nonRoot If false then this only works if the activity is the root
8580     *                of a task; if true it will work for any activity in a task.
8581     * @return Returns true if the move completed, false if not.
8582     */
8583    @Override
8584    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
8585        enforceNotIsolatedCaller("moveActivityTaskToBack");
8586        synchronized(this) {
8587            final long origId = Binder.clearCallingIdentity();
8588            try {
8589                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
8590                if (taskId >= 0) {
8591                    if ((mStackSupervisor.mLockTaskModeTask != null)
8592                            && (mStackSupervisor.mLockTaskModeTask.taskId == taskId)) {
8593                        mStackSupervisor.showLockTaskToast();
8594                        return false;
8595                    }
8596                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
8597                }
8598            } finally {
8599                Binder.restoreCallingIdentity(origId);
8600            }
8601        }
8602        return false;
8603    }
8604
8605    @Override
8606    public void moveTaskBackwards(int task) {
8607        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8608                "moveTaskBackwards()");
8609
8610        synchronized(this) {
8611            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8612                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
8613                return;
8614            }
8615            final long origId = Binder.clearCallingIdentity();
8616            moveTaskBackwardsLocked(task);
8617            Binder.restoreCallingIdentity(origId);
8618        }
8619    }
8620
8621    private final void moveTaskBackwardsLocked(int task) {
8622        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
8623    }
8624
8625    @Override
8626    public IBinder getHomeActivityToken() throws RemoteException {
8627        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8628                "getHomeActivityToken()");
8629        synchronized (this) {
8630            return mStackSupervisor.getHomeActivityToken();
8631        }
8632    }
8633
8634    @Override
8635    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
8636            IActivityContainerCallback callback) throws RemoteException {
8637        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8638                "createActivityContainer()");
8639        synchronized (this) {
8640            if (parentActivityToken == null) {
8641                throw new IllegalArgumentException("parent token must not be null");
8642            }
8643            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
8644            if (r == null) {
8645                return null;
8646            }
8647            if (callback == null) {
8648                throw new IllegalArgumentException("callback must not be null");
8649            }
8650            return mStackSupervisor.createActivityContainer(r, callback);
8651        }
8652    }
8653
8654    @Override
8655    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
8656        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8657                "deleteActivityContainer()");
8658        synchronized (this) {
8659            mStackSupervisor.deleteActivityContainer(container);
8660        }
8661    }
8662
8663    @Override
8664    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
8665            throws RemoteException {
8666        synchronized (this) {
8667            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
8668            if (stack != null) {
8669                return stack.mActivityContainer;
8670            }
8671            return null;
8672        }
8673    }
8674
8675    @Override
8676    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
8677        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8678                "moveTaskToStack()");
8679        if (stackId == HOME_STACK_ID) {
8680            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
8681                    new RuntimeException("here").fillInStackTrace());
8682        }
8683        synchronized (this) {
8684            long ident = Binder.clearCallingIdentity();
8685            try {
8686                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
8687                        + stackId + " toTop=" + toTop);
8688                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
8689            } finally {
8690                Binder.restoreCallingIdentity(ident);
8691            }
8692        }
8693    }
8694
8695    @Override
8696    public void resizeStack(int stackBoxId, Rect bounds) {
8697        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8698                "resizeStackBox()");
8699        long ident = Binder.clearCallingIdentity();
8700        try {
8701            mWindowManager.resizeStack(stackBoxId, bounds);
8702        } finally {
8703            Binder.restoreCallingIdentity(ident);
8704        }
8705    }
8706
8707    @Override
8708    public List<StackInfo> getAllStackInfos() {
8709        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8710                "getAllStackInfos()");
8711        long ident = Binder.clearCallingIdentity();
8712        try {
8713            synchronized (this) {
8714                return mStackSupervisor.getAllStackInfosLocked();
8715            }
8716        } finally {
8717            Binder.restoreCallingIdentity(ident);
8718        }
8719    }
8720
8721    @Override
8722    public StackInfo getStackInfo(int stackId) {
8723        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8724                "getStackInfo()");
8725        long ident = Binder.clearCallingIdentity();
8726        try {
8727            synchronized (this) {
8728                return mStackSupervisor.getStackInfoLocked(stackId);
8729            }
8730        } finally {
8731            Binder.restoreCallingIdentity(ident);
8732        }
8733    }
8734
8735    @Override
8736    public boolean isInHomeStack(int taskId) {
8737        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8738                "getStackInfo()");
8739        long ident = Binder.clearCallingIdentity();
8740        try {
8741            synchronized (this) {
8742                TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(taskId);
8743                return tr != null && tr.stack != null && tr.stack.isHomeStack();
8744            }
8745        } finally {
8746            Binder.restoreCallingIdentity(ident);
8747        }
8748    }
8749
8750    @Override
8751    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
8752        synchronized(this) {
8753            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
8754        }
8755    }
8756
8757    private boolean isLockTaskAuthorized(String pkg) {
8758        final DevicePolicyManager dpm = (DevicePolicyManager)
8759                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
8760        try {
8761            int uid = mContext.getPackageManager().getPackageUid(pkg,
8762                    Binder.getCallingUserHandle().getIdentifier());
8763            return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
8764        } catch (NameNotFoundException e) {
8765            return false;
8766        }
8767    }
8768
8769    void startLockTaskMode(TaskRecord task) {
8770        final String pkg;
8771        synchronized (this) {
8772            pkg = task.intent.getComponent().getPackageName();
8773        }
8774        boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID;
8775        if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) {
8776            StatusBarManagerInternal statusBarManager = LocalServices.getService(
8777                    StatusBarManagerInternal.class);
8778            if (statusBarManager != null) {
8779                statusBarManager.showScreenPinningRequest();
8780            }
8781            return;
8782        }
8783        long ident = Binder.clearCallingIdentity();
8784        try {
8785            synchronized (this) {
8786                // Since we lost lock on task, make sure it is still there.
8787                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
8788                if (task != null) {
8789                    if (!isSystemInitiated
8790                            && ((mStackSupervisor.getFocusedStack() == null)
8791                                    || (task != mStackSupervisor.getFocusedStack().topTask()))) {
8792                        throw new IllegalArgumentException("Invalid task, not in foreground");
8793                    }
8794                    mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated);
8795                }
8796            }
8797        } finally {
8798            Binder.restoreCallingIdentity(ident);
8799        }
8800    }
8801
8802    @Override
8803    public void startLockTaskMode(int taskId) {
8804        final TaskRecord task;
8805        long ident = Binder.clearCallingIdentity();
8806        try {
8807            synchronized (this) {
8808                task = mStackSupervisor.anyTaskForIdLocked(taskId);
8809            }
8810        } finally {
8811            Binder.restoreCallingIdentity(ident);
8812        }
8813        if (task != null) {
8814            startLockTaskMode(task);
8815        }
8816    }
8817
8818    @Override
8819    public void startLockTaskMode(IBinder token) {
8820        final TaskRecord task;
8821        long ident = Binder.clearCallingIdentity();
8822        try {
8823            synchronized (this) {
8824                final ActivityRecord r = ActivityRecord.forToken(token);
8825                if (r == null) {
8826                    return;
8827                }
8828                task = r.task;
8829            }
8830        } finally {
8831            Binder.restoreCallingIdentity(ident);
8832        }
8833        if (task != null) {
8834            startLockTaskMode(task);
8835        }
8836    }
8837
8838    @Override
8839    public void startLockTaskModeOnCurrent() throws RemoteException {
8840        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8841                "startLockTaskModeOnCurrent");
8842        long ident = Binder.clearCallingIdentity();
8843        try {
8844            ActivityRecord r = null;
8845            synchronized (this) {
8846                r = mStackSupervisor.topRunningActivityLocked();
8847            }
8848            startLockTaskMode(r.task);
8849        } finally {
8850            Binder.restoreCallingIdentity(ident);
8851        }
8852    }
8853
8854    @Override
8855    public void stopLockTaskMode() {
8856        // Verify that the user matches the package of the intent for the TaskRecord
8857        // we are locked to or systtem.  This will ensure the same caller for startLockTaskMode
8858        // and stopLockTaskMode.
8859        final int callingUid = Binder.getCallingUid();
8860        if (callingUid != Process.SYSTEM_UID) {
8861            try {
8862                String pkg =
8863                        mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName();
8864                int uid = mContext.getPackageManager().getPackageUid(pkg,
8865                        Binder.getCallingUserHandle().getIdentifier());
8866                if (uid != callingUid) {
8867                    throw new SecurityException("Invalid uid, expected " + uid);
8868                }
8869            } catch (NameNotFoundException e) {
8870                Log.d(TAG, "stopLockTaskMode " + e);
8871                return;
8872            }
8873        }
8874        long ident = Binder.clearCallingIdentity();
8875        try {
8876            Log.d(TAG, "stopLockTaskMode");
8877            // Stop lock task
8878            synchronized (this) {
8879                mStackSupervisor.setLockTaskModeLocked(null, false);
8880            }
8881        } finally {
8882            Binder.restoreCallingIdentity(ident);
8883        }
8884    }
8885
8886    @Override
8887    public void stopLockTaskModeOnCurrent() throws RemoteException {
8888        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8889                "stopLockTaskModeOnCurrent");
8890        long ident = Binder.clearCallingIdentity();
8891        try {
8892            stopLockTaskMode();
8893        } finally {
8894            Binder.restoreCallingIdentity(ident);
8895        }
8896    }
8897
8898    @Override
8899    public boolean isInLockTaskMode() {
8900        synchronized (this) {
8901            return mStackSupervisor.isInLockTaskMode();
8902        }
8903    }
8904
8905    // =========================================================
8906    // CONTENT PROVIDERS
8907    // =========================================================
8908
8909    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
8910        List<ProviderInfo> providers = null;
8911        try {
8912            providers = AppGlobals.getPackageManager().
8913                queryContentProviders(app.processName, app.uid,
8914                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
8915        } catch (RemoteException ex) {
8916        }
8917        if (DEBUG_MU)
8918            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
8919        int userId = app.userId;
8920        if (providers != null) {
8921            int N = providers.size();
8922            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
8923            for (int i=0; i<N; i++) {
8924                ProviderInfo cpi =
8925                    (ProviderInfo)providers.get(i);
8926                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8927                        cpi.name, cpi.flags);
8928                if (singleton && UserHandle.getUserId(app.uid) != 0) {
8929                    // This is a singleton provider, but a user besides the
8930                    // default user is asking to initialize a process it runs
8931                    // in...  well, no, it doesn't actually run in this process,
8932                    // it runs in the process of the default user.  Get rid of it.
8933                    providers.remove(i);
8934                    N--;
8935                    i--;
8936                    continue;
8937                }
8938
8939                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8940                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
8941                if (cpr == null) {
8942                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
8943                    mProviderMap.putProviderByClass(comp, cpr);
8944                }
8945                if (DEBUG_MU)
8946                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
8947                app.pubProviders.put(cpi.name, cpr);
8948                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
8949                    // Don't add this if it is a platform component that is marked
8950                    // to run in multiple processes, because this is actually
8951                    // part of the framework so doesn't make sense to track as a
8952                    // separate apk in the process.
8953                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
8954                            mProcessStats);
8955                }
8956                ensurePackageDexOpt(cpi.applicationInfo.packageName);
8957            }
8958        }
8959        return providers;
8960    }
8961
8962    /**
8963     * Check if {@link ProcessRecord} has a possible chance at accessing the
8964     * given {@link ProviderInfo}. Final permission checking is always done
8965     * in {@link ContentProvider}.
8966     */
8967    private final String checkContentProviderPermissionLocked(
8968            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
8969        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
8970        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
8971        boolean checkedGrants = false;
8972        if (checkUser) {
8973            // Looking for cross-user grants before enforcing the typical cross-users permissions
8974            int tmpTargetUserId = unsafeConvertIncomingUser(userId);
8975            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
8976                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
8977                    return null;
8978                }
8979                checkedGrants = true;
8980            }
8981            userId = handleIncomingUser(callingPid, callingUid, userId,
8982                    false, ALLOW_NON_FULL,
8983                    "checkContentProviderPermissionLocked " + cpi.authority, null);
8984            if (userId != tmpTargetUserId) {
8985                // When we actually went to determine the final targer user ID, this ended
8986                // up different than our initial check for the authority.  This is because
8987                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
8988                // SELF.  So we need to re-check the grants again.
8989                checkedGrants = false;
8990            }
8991        }
8992        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
8993                cpi.applicationInfo.uid, cpi.exported)
8994                == PackageManager.PERMISSION_GRANTED) {
8995            return null;
8996        }
8997        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
8998                cpi.applicationInfo.uid, cpi.exported)
8999                == PackageManager.PERMISSION_GRANTED) {
9000            return null;
9001        }
9002
9003        PathPermission[] pps = cpi.pathPermissions;
9004        if (pps != null) {
9005            int i = pps.length;
9006            while (i > 0) {
9007                i--;
9008                PathPermission pp = pps[i];
9009                String pprperm = pp.getReadPermission();
9010                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
9011                        cpi.applicationInfo.uid, cpi.exported)
9012                        == PackageManager.PERMISSION_GRANTED) {
9013                    return null;
9014                }
9015                String ppwperm = pp.getWritePermission();
9016                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
9017                        cpi.applicationInfo.uid, cpi.exported)
9018                        == PackageManager.PERMISSION_GRANTED) {
9019                    return null;
9020                }
9021            }
9022        }
9023        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
9024            return null;
9025        }
9026
9027        String msg;
9028        if (!cpi.exported) {
9029            msg = "Permission Denial: opening provider " + cpi.name
9030                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9031                    + ", uid=" + callingUid + ") that is not exported from uid "
9032                    + cpi.applicationInfo.uid;
9033        } else {
9034            msg = "Permission Denial: opening provider " + cpi.name
9035                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9036                    + ", uid=" + callingUid + ") requires "
9037                    + cpi.readPermission + " or " + cpi.writePermission;
9038        }
9039        Slog.w(TAG, msg);
9040        return msg;
9041    }
9042
9043    /**
9044     * Returns if the ContentProvider has granted a uri to callingUid
9045     */
9046    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
9047        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
9048        if (perms != null) {
9049            for (int i=perms.size()-1; i>=0; i--) {
9050                GrantUri grantUri = perms.keyAt(i);
9051                if (grantUri.sourceUserId == userId || !checkUser) {
9052                    if (matchesProvider(grantUri.uri, cpi)) {
9053                        return true;
9054                    }
9055                }
9056            }
9057        }
9058        return false;
9059    }
9060
9061    /**
9062     * Returns true if the uri authority is one of the authorities specified in the provider.
9063     */
9064    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
9065        String uriAuth = uri.getAuthority();
9066        String cpiAuth = cpi.authority;
9067        if (cpiAuth.indexOf(';') == -1) {
9068            return cpiAuth.equals(uriAuth);
9069        }
9070        String[] cpiAuths = cpiAuth.split(";");
9071        int length = cpiAuths.length;
9072        for (int i = 0; i < length; i++) {
9073            if (cpiAuths[i].equals(uriAuth)) return true;
9074        }
9075        return false;
9076    }
9077
9078    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
9079            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9080        if (r != null) {
9081            for (int i=0; i<r.conProviders.size(); i++) {
9082                ContentProviderConnection conn = r.conProviders.get(i);
9083                if (conn.provider == cpr) {
9084                    if (DEBUG_PROVIDER) Slog.v(TAG,
9085                            "Adding provider requested by "
9086                            + r.processName + " from process "
9087                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9088                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9089                    if (stable) {
9090                        conn.stableCount++;
9091                        conn.numStableIncs++;
9092                    } else {
9093                        conn.unstableCount++;
9094                        conn.numUnstableIncs++;
9095                    }
9096                    return conn;
9097                }
9098            }
9099            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
9100            if (stable) {
9101                conn.stableCount = 1;
9102                conn.numStableIncs = 1;
9103            } else {
9104                conn.unstableCount = 1;
9105                conn.numUnstableIncs = 1;
9106            }
9107            cpr.connections.add(conn);
9108            r.conProviders.add(conn);
9109            startAssociationLocked(r.uid, r.processName, cpr.uid, cpr.name, cpr.info.processName);
9110            return conn;
9111        }
9112        cpr.addExternalProcessHandleLocked(externalProcessToken);
9113        return null;
9114    }
9115
9116    boolean decProviderCountLocked(ContentProviderConnection conn,
9117            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9118        if (conn != null) {
9119            cpr = conn.provider;
9120            if (DEBUG_PROVIDER) Slog.v(TAG,
9121                    "Removing provider requested by "
9122                    + conn.client.processName + " from process "
9123                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9124                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9125            if (stable) {
9126                conn.stableCount--;
9127            } else {
9128                conn.unstableCount--;
9129            }
9130            if (conn.stableCount == 0 && conn.unstableCount == 0) {
9131                cpr.connections.remove(conn);
9132                conn.client.conProviders.remove(conn);
9133                stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
9134                return true;
9135            }
9136            return false;
9137        }
9138        cpr.removeExternalProcessHandleLocked(externalProcessToken);
9139        return false;
9140    }
9141
9142    private void checkTime(long startTime, String where) {
9143        long now = SystemClock.elapsedRealtime();
9144        if ((now-startTime) > 1000) {
9145            // If we are taking more than a second, log about it.
9146            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
9147        }
9148    }
9149
9150    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
9151            String name, IBinder token, boolean stable, int userId) {
9152        ContentProviderRecord cpr;
9153        ContentProviderConnection conn = null;
9154        ProviderInfo cpi = null;
9155
9156        synchronized(this) {
9157            long startTime = SystemClock.elapsedRealtime();
9158
9159            ProcessRecord r = null;
9160            if (caller != null) {
9161                r = getRecordForAppLocked(caller);
9162                if (r == null) {
9163                    throw new SecurityException(
9164                            "Unable to find app for caller " + caller
9165                          + " (pid=" + Binder.getCallingPid()
9166                          + ") when getting content provider " + name);
9167                }
9168            }
9169
9170            boolean checkCrossUser = true;
9171
9172            checkTime(startTime, "getContentProviderImpl: getProviderByName");
9173
9174            // First check if this content provider has been published...
9175            cpr = mProviderMap.getProviderByName(name, userId);
9176            // If that didn't work, check if it exists for user 0 and then
9177            // verify that it's a singleton provider before using it.
9178            if (cpr == null && userId != UserHandle.USER_OWNER) {
9179                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
9180                if (cpr != null) {
9181                    cpi = cpr.info;
9182                    if (isSingleton(cpi.processName, cpi.applicationInfo,
9183                            cpi.name, cpi.flags)
9184                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
9185                        userId = UserHandle.USER_OWNER;
9186                        checkCrossUser = false;
9187                    } else {
9188                        cpr = null;
9189                        cpi = null;
9190                    }
9191                }
9192            }
9193
9194            boolean providerRunning = cpr != null;
9195            if (providerRunning) {
9196                cpi = cpr.info;
9197                String msg;
9198                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9199                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
9200                        != null) {
9201                    throw new SecurityException(msg);
9202                }
9203                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9204
9205                if (r != null && cpr.canRunHere(r)) {
9206                    // This provider has been published or is in the process
9207                    // of being published...  but it is also allowed to run
9208                    // in the caller's process, so don't make a connection
9209                    // and just let the caller instantiate its own instance.
9210                    ContentProviderHolder holder = cpr.newHolder(null);
9211                    // don't give caller the provider object, it needs
9212                    // to make its own.
9213                    holder.provider = null;
9214                    return holder;
9215                }
9216
9217                final long origId = Binder.clearCallingIdentity();
9218
9219                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
9220
9221                // In this case the provider instance already exists, so we can
9222                // return it right away.
9223                conn = incProviderCountLocked(r, cpr, token, stable);
9224                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
9225                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
9226                        // If this is a perceptible app accessing the provider,
9227                        // make sure to count it as being accessed and thus
9228                        // back up on the LRU list.  This is good because
9229                        // content providers are often expensive to start.
9230                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
9231                        updateLruProcessLocked(cpr.proc, false, null);
9232                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
9233                    }
9234                }
9235
9236                if (cpr.proc != null) {
9237                    if (false) {
9238                        if (cpr.name.flattenToShortString().equals(
9239                                "com.android.providers.calendar/.CalendarProvider2")) {
9240                            Slog.v(TAG, "****************** KILLING "
9241                                + cpr.name.flattenToShortString());
9242                            Process.killProcess(cpr.proc.pid);
9243                        }
9244                    }
9245                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
9246                    boolean success = updateOomAdjLocked(cpr.proc);
9247                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
9248                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
9249                    // NOTE: there is still a race here where a signal could be
9250                    // pending on the process even though we managed to update its
9251                    // adj level.  Not sure what to do about this, but at least
9252                    // the race is now smaller.
9253                    if (!success) {
9254                        // Uh oh...  it looks like the provider's process
9255                        // has been killed on us.  We need to wait for a new
9256                        // process to be started, and make sure its death
9257                        // doesn't kill our process.
9258                        Slog.i(TAG,
9259                                "Existing provider " + cpr.name.flattenToShortString()
9260                                + " is crashing; detaching " + r);
9261                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
9262                        checkTime(startTime, "getContentProviderImpl: before appDied");
9263                        appDiedLocked(cpr.proc);
9264                        checkTime(startTime, "getContentProviderImpl: after appDied");
9265                        if (!lastRef) {
9266                            // This wasn't the last ref our process had on
9267                            // the provider...  we have now been killed, bail.
9268                            return null;
9269                        }
9270                        providerRunning = false;
9271                        conn = null;
9272                    }
9273                }
9274
9275                Binder.restoreCallingIdentity(origId);
9276            }
9277
9278            boolean singleton;
9279            if (!providerRunning) {
9280                try {
9281                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
9282                    cpi = AppGlobals.getPackageManager().
9283                        resolveContentProvider(name,
9284                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
9285                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
9286                } catch (RemoteException ex) {
9287                }
9288                if (cpi == null) {
9289                    return null;
9290                }
9291                // If the provider is a singleton AND
9292                // (it's a call within the same user || the provider is a
9293                // privileged app)
9294                // Then allow connecting to the singleton provider
9295                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9296                        cpi.name, cpi.flags)
9297                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
9298                if (singleton) {
9299                    userId = UserHandle.USER_OWNER;
9300                }
9301                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
9302                checkTime(startTime, "getContentProviderImpl: got app info for user");
9303
9304                String msg;
9305                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9306                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
9307                        != null) {
9308                    throw new SecurityException(msg);
9309                }
9310                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9311
9312                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
9313                        && !cpi.processName.equals("system")) {
9314                    // If this content provider does not run in the system
9315                    // process, and the system is not yet ready to run other
9316                    // processes, then fail fast instead of hanging.
9317                    throw new IllegalArgumentException(
9318                            "Attempt to launch content provider before system ready");
9319                }
9320
9321                // Make sure that the user who owns this provider is running.  If not,
9322                // we don't want to allow it to run.
9323                if (!isUserRunningLocked(userId, false)) {
9324                    Slog.w(TAG, "Unable to launch app "
9325                            + cpi.applicationInfo.packageName + "/"
9326                            + cpi.applicationInfo.uid + " for provider "
9327                            + name + ": user " + userId + " is stopped");
9328                    return null;
9329                }
9330
9331                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9332                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
9333                cpr = mProviderMap.getProviderByClass(comp, userId);
9334                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
9335                final boolean firstClass = cpr == null;
9336                if (firstClass) {
9337                    final long ident = Binder.clearCallingIdentity();
9338                    try {
9339                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
9340                        ApplicationInfo ai =
9341                            AppGlobals.getPackageManager().
9342                                getApplicationInfo(
9343                                        cpi.applicationInfo.packageName,
9344                                        STOCK_PM_FLAGS, userId);
9345                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
9346                        if (ai == null) {
9347                            Slog.w(TAG, "No package info for content provider "
9348                                    + cpi.name);
9349                            return null;
9350                        }
9351                        ai = getAppInfoForUser(ai, userId);
9352                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
9353                    } catch (RemoteException ex) {
9354                        // pm is in same process, this will never happen.
9355                    } finally {
9356                        Binder.restoreCallingIdentity(ident);
9357                    }
9358                }
9359
9360                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
9361
9362                if (r != null && cpr.canRunHere(r)) {
9363                    // If this is a multiprocess provider, then just return its
9364                    // info and allow the caller to instantiate it.  Only do
9365                    // this if the provider is the same user as the caller's
9366                    // process, or can run as root (so can be in any process).
9367                    return cpr.newHolder(null);
9368                }
9369
9370                if (DEBUG_PROVIDER) {
9371                    RuntimeException e = new RuntimeException("here");
9372                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
9373                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
9374                }
9375
9376                // This is single process, and our app is now connecting to it.
9377                // See if we are already in the process of launching this
9378                // provider.
9379                final int N = mLaunchingProviders.size();
9380                int i;
9381                for (i=0; i<N; i++) {
9382                    if (mLaunchingProviders.get(i) == cpr) {
9383                        break;
9384                    }
9385                }
9386
9387                // If the provider is not already being launched, then get it
9388                // started.
9389                if (i >= N) {
9390                    final long origId = Binder.clearCallingIdentity();
9391
9392                    try {
9393                        // Content provider is now in use, its package can't be stopped.
9394                        try {
9395                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
9396                            AppGlobals.getPackageManager().setPackageStoppedState(
9397                                    cpr.appInfo.packageName, false, userId);
9398                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
9399                        } catch (RemoteException e) {
9400                        } catch (IllegalArgumentException e) {
9401                            Slog.w(TAG, "Failed trying to unstop package "
9402                                    + cpr.appInfo.packageName + ": " + e);
9403                        }
9404
9405                        // Use existing process if already started
9406                        checkTime(startTime, "getContentProviderImpl: looking for process record");
9407                        ProcessRecord proc = getProcessRecordLocked(
9408                                cpi.processName, cpr.appInfo.uid, false);
9409                        if (proc != null && proc.thread != null) {
9410                            if (DEBUG_PROVIDER) {
9411                                Slog.d(TAG, "Installing in existing process " + proc);
9412                            }
9413                            checkTime(startTime, "getContentProviderImpl: scheduling install");
9414                            proc.pubProviders.put(cpi.name, cpr);
9415                            try {
9416                                proc.thread.scheduleInstallProvider(cpi);
9417                            } catch (RemoteException e) {
9418                            }
9419                        } else {
9420                            checkTime(startTime, "getContentProviderImpl: before start process");
9421                            proc = startProcessLocked(cpi.processName,
9422                                    cpr.appInfo, false, 0, "content provider",
9423                                    new ComponentName(cpi.applicationInfo.packageName,
9424                                            cpi.name), false, false, false);
9425                            checkTime(startTime, "getContentProviderImpl: after start process");
9426                            if (proc == null) {
9427                                Slog.w(TAG, "Unable to launch app "
9428                                        + cpi.applicationInfo.packageName + "/"
9429                                        + cpi.applicationInfo.uid + " for provider "
9430                                        + name + ": process is bad");
9431                                return null;
9432                            }
9433                        }
9434                        cpr.launchingApp = proc;
9435                        mLaunchingProviders.add(cpr);
9436                    } finally {
9437                        Binder.restoreCallingIdentity(origId);
9438                    }
9439                }
9440
9441                checkTime(startTime, "getContentProviderImpl: updating data structures");
9442
9443                // Make sure the provider is published (the same provider class
9444                // may be published under multiple names).
9445                if (firstClass) {
9446                    mProviderMap.putProviderByClass(comp, cpr);
9447                }
9448
9449                mProviderMap.putProviderByName(name, cpr);
9450                conn = incProviderCountLocked(r, cpr, token, stable);
9451                if (conn != null) {
9452                    conn.waiting = true;
9453                }
9454            }
9455            checkTime(startTime, "getContentProviderImpl: done!");
9456        }
9457
9458        // Wait for the provider to be published...
9459        synchronized (cpr) {
9460            while (cpr.provider == null) {
9461                if (cpr.launchingApp == null) {
9462                    Slog.w(TAG, "Unable to launch app "
9463                            + cpi.applicationInfo.packageName + "/"
9464                            + cpi.applicationInfo.uid + " for provider "
9465                            + name + ": launching app became null");
9466                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
9467                            UserHandle.getUserId(cpi.applicationInfo.uid),
9468                            cpi.applicationInfo.packageName,
9469                            cpi.applicationInfo.uid, name);
9470                    return null;
9471                }
9472                try {
9473                    if (DEBUG_MU) {
9474                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
9475                                + cpr.launchingApp);
9476                    }
9477                    if (conn != null) {
9478                        conn.waiting = true;
9479                    }
9480                    cpr.wait();
9481                } catch (InterruptedException ex) {
9482                } finally {
9483                    if (conn != null) {
9484                        conn.waiting = false;
9485                    }
9486                }
9487            }
9488        }
9489        return cpr != null ? cpr.newHolder(conn) : null;
9490    }
9491
9492    @Override
9493    public final ContentProviderHolder getContentProvider(
9494            IApplicationThread caller, String name, int userId, boolean stable) {
9495        enforceNotIsolatedCaller("getContentProvider");
9496        if (caller == null) {
9497            String msg = "null IApplicationThread when getting content provider "
9498                    + name;
9499            Slog.w(TAG, msg);
9500            throw new SecurityException(msg);
9501        }
9502        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
9503        // with cross-user grant.
9504        return getContentProviderImpl(caller, name, null, stable, userId);
9505    }
9506
9507    public ContentProviderHolder getContentProviderExternal(
9508            String name, int userId, IBinder token) {
9509        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9510            "Do not have permission in call getContentProviderExternal()");
9511        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
9512                false, ALLOW_FULL_ONLY, "getContentProvider", null);
9513        return getContentProviderExternalUnchecked(name, token, userId);
9514    }
9515
9516    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
9517            IBinder token, int userId) {
9518        return getContentProviderImpl(null, name, token, true, userId);
9519    }
9520
9521    /**
9522     * Drop a content provider from a ProcessRecord's bookkeeping
9523     */
9524    public void removeContentProvider(IBinder connection, boolean stable) {
9525        enforceNotIsolatedCaller("removeContentProvider");
9526        long ident = Binder.clearCallingIdentity();
9527        try {
9528            synchronized (this) {
9529                ContentProviderConnection conn;
9530                try {
9531                    conn = (ContentProviderConnection)connection;
9532                } catch (ClassCastException e) {
9533                    String msg ="removeContentProvider: " + connection
9534                            + " not a ContentProviderConnection";
9535                    Slog.w(TAG, msg);
9536                    throw new IllegalArgumentException(msg);
9537                }
9538                if (conn == null) {
9539                    throw new NullPointerException("connection is null");
9540                }
9541                if (decProviderCountLocked(conn, null, null, stable)) {
9542                    updateOomAdjLocked();
9543                }
9544            }
9545        } finally {
9546            Binder.restoreCallingIdentity(ident);
9547        }
9548    }
9549
9550    public void removeContentProviderExternal(String name, IBinder token) {
9551        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9552            "Do not have permission in call removeContentProviderExternal()");
9553        int userId = UserHandle.getCallingUserId();
9554        long ident = Binder.clearCallingIdentity();
9555        try {
9556            removeContentProviderExternalUnchecked(name, token, userId);
9557        } finally {
9558            Binder.restoreCallingIdentity(ident);
9559        }
9560    }
9561
9562    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
9563        synchronized (this) {
9564            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
9565            if(cpr == null) {
9566                //remove from mProvidersByClass
9567                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
9568                return;
9569            }
9570
9571            //update content provider record entry info
9572            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
9573            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
9574            if (localCpr.hasExternalProcessHandles()) {
9575                if (localCpr.removeExternalProcessHandleLocked(token)) {
9576                    updateOomAdjLocked();
9577                } else {
9578                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
9579                            + " with no external reference for token: "
9580                            + token + ".");
9581                }
9582            } else {
9583                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
9584                        + " with no external references.");
9585            }
9586        }
9587    }
9588
9589    public final void publishContentProviders(IApplicationThread caller,
9590            List<ContentProviderHolder> providers) {
9591        if (providers == null) {
9592            return;
9593        }
9594
9595        enforceNotIsolatedCaller("publishContentProviders");
9596        synchronized (this) {
9597            final ProcessRecord r = getRecordForAppLocked(caller);
9598            if (DEBUG_MU)
9599                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
9600            if (r == null) {
9601                throw new SecurityException(
9602                        "Unable to find app for caller " + caller
9603                      + " (pid=" + Binder.getCallingPid()
9604                      + ") when publishing content providers");
9605            }
9606
9607            final long origId = Binder.clearCallingIdentity();
9608
9609            final int N = providers.size();
9610            for (int i=0; i<N; i++) {
9611                ContentProviderHolder src = providers.get(i);
9612                if (src == null || src.info == null || src.provider == null) {
9613                    continue;
9614                }
9615                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
9616                if (DEBUG_MU)
9617                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
9618                if (dst != null) {
9619                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
9620                    mProviderMap.putProviderByClass(comp, dst);
9621                    String names[] = dst.info.authority.split(";");
9622                    for (int j = 0; j < names.length; j++) {
9623                        mProviderMap.putProviderByName(names[j], dst);
9624                    }
9625
9626                    int NL = mLaunchingProviders.size();
9627                    int j;
9628                    for (j=0; j<NL; j++) {
9629                        if (mLaunchingProviders.get(j) == dst) {
9630                            mLaunchingProviders.remove(j);
9631                            j--;
9632                            NL--;
9633                        }
9634                    }
9635                    synchronized (dst) {
9636                        dst.provider = src.provider;
9637                        dst.proc = r;
9638                        dst.notifyAll();
9639                    }
9640                    updateOomAdjLocked(r);
9641                }
9642            }
9643
9644            Binder.restoreCallingIdentity(origId);
9645        }
9646    }
9647
9648    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
9649        ContentProviderConnection conn;
9650        try {
9651            conn = (ContentProviderConnection)connection;
9652        } catch (ClassCastException e) {
9653            String msg ="refContentProvider: " + connection
9654                    + " not a ContentProviderConnection";
9655            Slog.w(TAG, msg);
9656            throw new IllegalArgumentException(msg);
9657        }
9658        if (conn == null) {
9659            throw new NullPointerException("connection is null");
9660        }
9661
9662        synchronized (this) {
9663            if (stable > 0) {
9664                conn.numStableIncs += stable;
9665            }
9666            stable = conn.stableCount + stable;
9667            if (stable < 0) {
9668                throw new IllegalStateException("stableCount < 0: " + stable);
9669            }
9670
9671            if (unstable > 0) {
9672                conn.numUnstableIncs += unstable;
9673            }
9674            unstable = conn.unstableCount + unstable;
9675            if (unstable < 0) {
9676                throw new IllegalStateException("unstableCount < 0: " + unstable);
9677            }
9678
9679            if ((stable+unstable) <= 0) {
9680                throw new IllegalStateException("ref counts can't go to zero here: stable="
9681                        + stable + " unstable=" + unstable);
9682            }
9683            conn.stableCount = stable;
9684            conn.unstableCount = unstable;
9685            return !conn.dead;
9686        }
9687    }
9688
9689    public void unstableProviderDied(IBinder connection) {
9690        ContentProviderConnection conn;
9691        try {
9692            conn = (ContentProviderConnection)connection;
9693        } catch (ClassCastException e) {
9694            String msg ="refContentProvider: " + connection
9695                    + " not a ContentProviderConnection";
9696            Slog.w(TAG, msg);
9697            throw new IllegalArgumentException(msg);
9698        }
9699        if (conn == null) {
9700            throw new NullPointerException("connection is null");
9701        }
9702
9703        // Safely retrieve the content provider associated with the connection.
9704        IContentProvider provider;
9705        synchronized (this) {
9706            provider = conn.provider.provider;
9707        }
9708
9709        if (provider == null) {
9710            // Um, yeah, we're way ahead of you.
9711            return;
9712        }
9713
9714        // Make sure the caller is being honest with us.
9715        if (provider.asBinder().pingBinder()) {
9716            // Er, no, still looks good to us.
9717            synchronized (this) {
9718                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
9719                        + " says " + conn + " died, but we don't agree");
9720                return;
9721            }
9722        }
9723
9724        // Well look at that!  It's dead!
9725        synchronized (this) {
9726            if (conn.provider.provider != provider) {
9727                // But something changed...  good enough.
9728                return;
9729            }
9730
9731            ProcessRecord proc = conn.provider.proc;
9732            if (proc == null || proc.thread == null) {
9733                // Seems like the process is already cleaned up.
9734                return;
9735            }
9736
9737            // As far as we're concerned, this is just like receiving a
9738            // death notification...  just a bit prematurely.
9739            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
9740                    + ") early provider death");
9741            final long ident = Binder.clearCallingIdentity();
9742            try {
9743                appDiedLocked(proc);
9744            } finally {
9745                Binder.restoreCallingIdentity(ident);
9746            }
9747        }
9748    }
9749
9750    @Override
9751    public void appNotRespondingViaProvider(IBinder connection) {
9752        enforceCallingPermission(
9753                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
9754
9755        final ContentProviderConnection conn = (ContentProviderConnection) connection;
9756        if (conn == null) {
9757            Slog.w(TAG, "ContentProviderConnection is null");
9758            return;
9759        }
9760
9761        final ProcessRecord host = conn.provider.proc;
9762        if (host == null) {
9763            Slog.w(TAG, "Failed to find hosting ProcessRecord");
9764            return;
9765        }
9766
9767        final long token = Binder.clearCallingIdentity();
9768        try {
9769            appNotResponding(host, null, null, false, "ContentProvider not responding");
9770        } finally {
9771            Binder.restoreCallingIdentity(token);
9772        }
9773    }
9774
9775    public final void installSystemProviders() {
9776        List<ProviderInfo> providers;
9777        synchronized (this) {
9778            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
9779            providers = generateApplicationProvidersLocked(app);
9780            if (providers != null) {
9781                for (int i=providers.size()-1; i>=0; i--) {
9782                    ProviderInfo pi = (ProviderInfo)providers.get(i);
9783                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
9784                        Slog.w(TAG, "Not installing system proc provider " + pi.name
9785                                + ": not system .apk");
9786                        providers.remove(i);
9787                    }
9788                }
9789            }
9790        }
9791        if (providers != null) {
9792            mSystemThread.installSystemProviders(providers);
9793        }
9794
9795        mCoreSettingsObserver = new CoreSettingsObserver(this);
9796
9797        //mUsageStatsService.monitorPackages();
9798    }
9799
9800    /**
9801     * Allows apps to retrieve the MIME type of a URI.
9802     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
9803     * users, then it does not need permission to access the ContentProvider.
9804     * Either, it needs cross-user uri grants.
9805     *
9806     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
9807     *
9808     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
9809     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
9810     */
9811    public String getProviderMimeType(Uri uri, int userId) {
9812        enforceNotIsolatedCaller("getProviderMimeType");
9813        final String name = uri.getAuthority();
9814        int callingUid = Binder.getCallingUid();
9815        int callingPid = Binder.getCallingPid();
9816        long ident = 0;
9817        boolean clearedIdentity = false;
9818        userId = unsafeConvertIncomingUser(userId);
9819        if (canClearIdentity(callingPid, callingUid, userId)) {
9820            clearedIdentity = true;
9821            ident = Binder.clearCallingIdentity();
9822        }
9823        ContentProviderHolder holder = null;
9824        try {
9825            holder = getContentProviderExternalUnchecked(name, null, userId);
9826            if (holder != null) {
9827                return holder.provider.getType(uri);
9828            }
9829        } catch (RemoteException e) {
9830            Log.w(TAG, "Content provider dead retrieving " + uri, e);
9831            return null;
9832        } finally {
9833            // We need to clear the identity to call removeContentProviderExternalUnchecked
9834            if (!clearedIdentity) {
9835                ident = Binder.clearCallingIdentity();
9836            }
9837            try {
9838                if (holder != null) {
9839                    removeContentProviderExternalUnchecked(name, null, userId);
9840                }
9841            } finally {
9842                Binder.restoreCallingIdentity(ident);
9843            }
9844        }
9845
9846        return null;
9847    }
9848
9849    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
9850        if (UserHandle.getUserId(callingUid) == userId) {
9851            return true;
9852        }
9853        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
9854                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
9855                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
9856                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
9857                return true;
9858        }
9859        return false;
9860    }
9861
9862    // =========================================================
9863    // GLOBAL MANAGEMENT
9864    // =========================================================
9865
9866    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
9867            boolean isolated, int isolatedUid) {
9868        String proc = customProcess != null ? customProcess : info.processName;
9869        BatteryStatsImpl.Uid.Proc ps = null;
9870        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9871        int uid = info.uid;
9872        if (isolated) {
9873            if (isolatedUid == 0) {
9874                int userId = UserHandle.getUserId(uid);
9875                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
9876                while (true) {
9877                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
9878                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
9879                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
9880                    }
9881                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
9882                    mNextIsolatedProcessUid++;
9883                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
9884                        // No process for this uid, use it.
9885                        break;
9886                    }
9887                    stepsLeft--;
9888                    if (stepsLeft <= 0) {
9889                        return null;
9890                    }
9891                }
9892            } else {
9893                // Special case for startIsolatedProcess (internal only), where
9894                // the uid of the isolated process is specified by the caller.
9895                uid = isolatedUid;
9896            }
9897        }
9898        return new ProcessRecord(stats, info, proc, uid);
9899    }
9900
9901    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
9902            String abiOverride) {
9903        ProcessRecord app;
9904        if (!isolated) {
9905            app = getProcessRecordLocked(info.processName, info.uid, true);
9906        } else {
9907            app = null;
9908        }
9909
9910        if (app == null) {
9911            app = newProcessRecordLocked(info, null, isolated, 0);
9912            mProcessNames.put(info.processName, app.uid, app);
9913            if (isolated) {
9914                mIsolatedProcesses.put(app.uid, app);
9915            }
9916            updateLruProcessLocked(app, false, null);
9917            updateOomAdjLocked();
9918        }
9919
9920        // This package really, really can not be stopped.
9921        try {
9922            AppGlobals.getPackageManager().setPackageStoppedState(
9923                    info.packageName, false, UserHandle.getUserId(app.uid));
9924        } catch (RemoteException e) {
9925        } catch (IllegalArgumentException e) {
9926            Slog.w(TAG, "Failed trying to unstop package "
9927                    + info.packageName + ": " + e);
9928        }
9929
9930        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
9931                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
9932            app.persistent = true;
9933            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
9934        }
9935        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
9936            mPersistentStartingProcesses.add(app);
9937            startProcessLocked(app, "added application", app.processName, abiOverride,
9938                    null /* entryPoint */, null /* entryPointArgs */);
9939        }
9940
9941        return app;
9942    }
9943
9944    public void unhandledBack() {
9945        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
9946                "unhandledBack()");
9947
9948        synchronized(this) {
9949            final long origId = Binder.clearCallingIdentity();
9950            try {
9951                getFocusedStack().unhandledBackLocked();
9952            } finally {
9953                Binder.restoreCallingIdentity(origId);
9954            }
9955        }
9956    }
9957
9958    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
9959        enforceNotIsolatedCaller("openContentUri");
9960        final int userId = UserHandle.getCallingUserId();
9961        String name = uri.getAuthority();
9962        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
9963        ParcelFileDescriptor pfd = null;
9964        if (cph != null) {
9965            // We record the binder invoker's uid in thread-local storage before
9966            // going to the content provider to open the file.  Later, in the code
9967            // that handles all permissions checks, we look for this uid and use
9968            // that rather than the Activity Manager's own uid.  The effect is that
9969            // we do the check against the caller's permissions even though it looks
9970            // to the content provider like the Activity Manager itself is making
9971            // the request.
9972            Binder token = new Binder();
9973            sCallerIdentity.set(new Identity(
9974                    token, Binder.getCallingPid(), Binder.getCallingUid()));
9975            try {
9976                pfd = cph.provider.openFile(null, uri, "r", null, token);
9977            } catch (FileNotFoundException e) {
9978                // do nothing; pfd will be returned null
9979            } finally {
9980                // Ensure that whatever happens, we clean up the identity state
9981                sCallerIdentity.remove();
9982            }
9983
9984            // We've got the fd now, so we're done with the provider.
9985            removeContentProviderExternalUnchecked(name, null, userId);
9986        } else {
9987            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
9988        }
9989        return pfd;
9990    }
9991
9992    // Actually is sleeping or shutting down or whatever else in the future
9993    // is an inactive state.
9994    public boolean isSleepingOrShuttingDown() {
9995        return isSleeping() || mShuttingDown;
9996    }
9997
9998    public boolean isSleeping() {
9999        return mSleeping;
10000    }
10001
10002    void onWakefulnessChanged(int wakefulness) {
10003        synchronized(this) {
10004            mWakefulness = wakefulness;
10005            updateSleepIfNeededLocked();
10006        }
10007    }
10008
10009    void finishRunningVoiceLocked() {
10010        if (mRunningVoice) {
10011            mRunningVoice = false;
10012            updateSleepIfNeededLocked();
10013        }
10014    }
10015
10016    void updateSleepIfNeededLocked() {
10017        if (mSleeping && !shouldSleepLocked()) {
10018            mSleeping = false;
10019            mStackSupervisor.comeOutOfSleepIfNeededLocked();
10020        } else if (!mSleeping && shouldSleepLocked()) {
10021            mSleeping = true;
10022            mStackSupervisor.goingToSleepLocked();
10023
10024            // Initialize the wake times of all processes.
10025            checkExcessivePowerUsageLocked(false);
10026            mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
10027            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
10028            mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
10029        }
10030    }
10031
10032    private boolean shouldSleepLocked() {
10033        // Resume applications while running a voice interactor.
10034        if (mRunningVoice) {
10035            return false;
10036        }
10037
10038        switch (mWakefulness) {
10039            case PowerManagerInternal.WAKEFULNESS_AWAKE:
10040            case PowerManagerInternal.WAKEFULNESS_DREAMING:
10041                // If we're interactive but applications are already paused then defer
10042                // resuming them until the lock screen is hidden.
10043                return mSleeping && mLockScreenShown != LOCK_SCREEN_HIDDEN;
10044            case PowerManagerInternal.WAKEFULNESS_DOZING:
10045                // If we're dozing then pause applications whenever the lock screen is shown.
10046                return mLockScreenShown != LOCK_SCREEN_HIDDEN;
10047            case PowerManagerInternal.WAKEFULNESS_ASLEEP:
10048            default:
10049                // If we're asleep then pause applications unconditionally.
10050                return true;
10051        }
10052    }
10053
10054    /** Pokes the task persister. */
10055    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
10056        if (task != null && task.stack != null && task.stack.isHomeStack()) {
10057            // Never persist the home stack.
10058            return;
10059        }
10060        mTaskPersister.wakeup(task, flush);
10061    }
10062
10063    /** Notifies all listeners when the task stack has changed. */
10064    void notifyTaskStackChangedLocked() {
10065        mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
10066        Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
10067        mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
10068    }
10069
10070    @Override
10071    public boolean shutdown(int timeout) {
10072        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
10073                != PackageManager.PERMISSION_GRANTED) {
10074            throw new SecurityException("Requires permission "
10075                    + android.Manifest.permission.SHUTDOWN);
10076        }
10077
10078        boolean timedout = false;
10079
10080        synchronized(this) {
10081            mShuttingDown = true;
10082            updateEventDispatchingLocked();
10083            timedout = mStackSupervisor.shutdownLocked(timeout);
10084        }
10085
10086        mAppOpsService.shutdown();
10087        if (mUsageStatsService != null) {
10088            mUsageStatsService.prepareShutdown();
10089        }
10090        mBatteryStatsService.shutdown();
10091        synchronized (this) {
10092            mProcessStats.shutdownLocked();
10093            notifyTaskPersisterLocked(null, true);
10094        }
10095
10096        return timedout;
10097    }
10098
10099    public final void activitySlept(IBinder token) {
10100        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
10101
10102        final long origId = Binder.clearCallingIdentity();
10103
10104        synchronized (this) {
10105            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10106            if (r != null) {
10107                mStackSupervisor.activitySleptLocked(r);
10108            }
10109        }
10110
10111        Binder.restoreCallingIdentity(origId);
10112    }
10113
10114    private String lockScreenShownToString() {
10115        switch (mLockScreenShown) {
10116            case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
10117            case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
10118            case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
10119            default: return "Unknown=" + mLockScreenShown;
10120        }
10121    }
10122
10123    void logLockScreen(String msg) {
10124        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg
10125                + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
10126                + PowerManagerInternal.wakefulnessToString(mWakefulness)
10127                + " mSleeping=" + mSleeping);
10128    }
10129
10130    void startRunningVoiceLocked() {
10131        if (!mRunningVoice) {
10132            mRunningVoice = true;
10133            updateSleepIfNeededLocked();
10134        }
10135    }
10136
10137    private void updateEventDispatchingLocked() {
10138        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
10139    }
10140
10141    public void setLockScreenShown(boolean shown) {
10142        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
10143                != PackageManager.PERMISSION_GRANTED) {
10144            throw new SecurityException("Requires permission "
10145                    + android.Manifest.permission.DEVICE_POWER);
10146        }
10147
10148        synchronized(this) {
10149            long ident = Binder.clearCallingIdentity();
10150            try {
10151                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
10152                mLockScreenShown = shown ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
10153                updateSleepIfNeededLocked();
10154            } finally {
10155                Binder.restoreCallingIdentity(ident);
10156            }
10157        }
10158    }
10159
10160    @Override
10161    public void stopAppSwitches() {
10162        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10163                != PackageManager.PERMISSION_GRANTED) {
10164            throw new SecurityException("Requires permission "
10165                    + android.Manifest.permission.STOP_APP_SWITCHES);
10166        }
10167
10168        synchronized(this) {
10169            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
10170                    + APP_SWITCH_DELAY_TIME;
10171            mDidAppSwitch = false;
10172            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10173            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10174            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
10175        }
10176    }
10177
10178    public void resumeAppSwitches() {
10179        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10180                != PackageManager.PERMISSION_GRANTED) {
10181            throw new SecurityException("Requires permission "
10182                    + android.Manifest.permission.STOP_APP_SWITCHES);
10183        }
10184
10185        synchronized(this) {
10186            // Note that we don't execute any pending app switches... we will
10187            // let those wait until either the timeout, or the next start
10188            // activity request.
10189            mAppSwitchesAllowedTime = 0;
10190        }
10191    }
10192
10193    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
10194            int callingPid, int callingUid, String name) {
10195        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
10196            return true;
10197        }
10198
10199        int perm = checkComponentPermission(
10200                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
10201                sourceUid, -1, true);
10202        if (perm == PackageManager.PERMISSION_GRANTED) {
10203            return true;
10204        }
10205
10206        // If the actual IPC caller is different from the logical source, then
10207        // also see if they are allowed to control app switches.
10208        if (callingUid != -1 && callingUid != sourceUid) {
10209            perm = checkComponentPermission(
10210                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
10211                    callingUid, -1, true);
10212            if (perm == PackageManager.PERMISSION_GRANTED) {
10213                return true;
10214            }
10215        }
10216
10217        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
10218        return false;
10219    }
10220
10221    public void setDebugApp(String packageName, boolean waitForDebugger,
10222            boolean persistent) {
10223        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
10224                "setDebugApp()");
10225
10226        long ident = Binder.clearCallingIdentity();
10227        try {
10228            // Note that this is not really thread safe if there are multiple
10229            // callers into it at the same time, but that's not a situation we
10230            // care about.
10231            if (persistent) {
10232                final ContentResolver resolver = mContext.getContentResolver();
10233                Settings.Global.putString(
10234                    resolver, Settings.Global.DEBUG_APP,
10235                    packageName);
10236                Settings.Global.putInt(
10237                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
10238                    waitForDebugger ? 1 : 0);
10239            }
10240
10241            synchronized (this) {
10242                if (!persistent) {
10243                    mOrigDebugApp = mDebugApp;
10244                    mOrigWaitForDebugger = mWaitForDebugger;
10245                }
10246                mDebugApp = packageName;
10247                mWaitForDebugger = waitForDebugger;
10248                mDebugTransient = !persistent;
10249                if (packageName != null) {
10250                    forceStopPackageLocked(packageName, -1, false, false, true, true,
10251                            false, UserHandle.USER_ALL, "set debug app");
10252                }
10253            }
10254        } finally {
10255            Binder.restoreCallingIdentity(ident);
10256        }
10257    }
10258
10259    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
10260        synchronized (this) {
10261            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10262            if (!isDebuggable) {
10263                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10264                    throw new SecurityException("Process not debuggable: " + app.packageName);
10265                }
10266            }
10267
10268            mOpenGlTraceApp = processName;
10269        }
10270    }
10271
10272    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
10273        synchronized (this) {
10274            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10275            if (!isDebuggable) {
10276                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10277                    throw new SecurityException("Process not debuggable: " + app.packageName);
10278                }
10279            }
10280            mProfileApp = processName;
10281            mProfileFile = profilerInfo.profileFile;
10282            if (mProfileFd != null) {
10283                try {
10284                    mProfileFd.close();
10285                } catch (IOException e) {
10286                }
10287                mProfileFd = null;
10288            }
10289            mProfileFd = profilerInfo.profileFd;
10290            mSamplingInterval = profilerInfo.samplingInterval;
10291            mAutoStopProfiler = profilerInfo.autoStopProfiler;
10292            mProfileType = 0;
10293        }
10294    }
10295
10296    @Override
10297    public void setAlwaysFinish(boolean enabled) {
10298        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
10299                "setAlwaysFinish()");
10300
10301        Settings.Global.putInt(
10302                mContext.getContentResolver(),
10303                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
10304
10305        synchronized (this) {
10306            mAlwaysFinishActivities = enabled;
10307        }
10308    }
10309
10310    @Override
10311    public void setActivityController(IActivityController controller) {
10312        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10313                "setActivityController()");
10314        synchronized (this) {
10315            mController = controller;
10316            Watchdog.getInstance().setActivityController(controller);
10317        }
10318    }
10319
10320    @Override
10321    public void setUserIsMonkey(boolean userIsMonkey) {
10322        synchronized (this) {
10323            synchronized (mPidsSelfLocked) {
10324                final int callingPid = Binder.getCallingPid();
10325                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
10326                if (precessRecord == null) {
10327                    throw new SecurityException("Unknown process: " + callingPid);
10328                }
10329                if (precessRecord.instrumentationUiAutomationConnection  == null) {
10330                    throw new SecurityException("Only an instrumentation process "
10331                            + "with a UiAutomation can call setUserIsMonkey");
10332                }
10333            }
10334            mUserIsMonkey = userIsMonkey;
10335        }
10336    }
10337
10338    @Override
10339    public boolean isUserAMonkey() {
10340        synchronized (this) {
10341            // If there is a controller also implies the user is a monkey.
10342            return (mUserIsMonkey || mController != null);
10343        }
10344    }
10345
10346    public void requestBugReport() {
10347        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
10348        SystemProperties.set("ctl.start", "bugreport");
10349    }
10350
10351    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
10352        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
10353    }
10354
10355    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
10356        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
10357            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
10358        }
10359        return KEY_DISPATCHING_TIMEOUT;
10360    }
10361
10362    @Override
10363    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
10364        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10365                != PackageManager.PERMISSION_GRANTED) {
10366            throw new SecurityException("Requires permission "
10367                    + android.Manifest.permission.FILTER_EVENTS);
10368        }
10369        ProcessRecord proc;
10370        long timeout;
10371        synchronized (this) {
10372            synchronized (mPidsSelfLocked) {
10373                proc = mPidsSelfLocked.get(pid);
10374            }
10375            timeout = getInputDispatchingTimeoutLocked(proc);
10376        }
10377
10378        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
10379            return -1;
10380        }
10381
10382        return timeout;
10383    }
10384
10385    /**
10386     * Handle input dispatching timeouts.
10387     * Returns whether input dispatching should be aborted or not.
10388     */
10389    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
10390            final ActivityRecord activity, final ActivityRecord parent,
10391            final boolean aboveSystem, String reason) {
10392        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10393                != PackageManager.PERMISSION_GRANTED) {
10394            throw new SecurityException("Requires permission "
10395                    + android.Manifest.permission.FILTER_EVENTS);
10396        }
10397
10398        final String annotation;
10399        if (reason == null) {
10400            annotation = "Input dispatching timed out";
10401        } else {
10402            annotation = "Input dispatching timed out (" + reason + ")";
10403        }
10404
10405        if (proc != null) {
10406            synchronized (this) {
10407                if (proc.debugging) {
10408                    return false;
10409                }
10410
10411                if (mDidDexOpt) {
10412                    // Give more time since we were dexopting.
10413                    mDidDexOpt = false;
10414                    return false;
10415                }
10416
10417                if (proc.instrumentationClass != null) {
10418                    Bundle info = new Bundle();
10419                    info.putString("shortMsg", "keyDispatchingTimedOut");
10420                    info.putString("longMsg", annotation);
10421                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
10422                    return true;
10423                }
10424            }
10425            mHandler.post(new Runnable() {
10426                @Override
10427                public void run() {
10428                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
10429                }
10430            });
10431        }
10432
10433        return true;
10434    }
10435
10436    public Bundle getAssistContextExtras(int requestType) {
10437        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null,
10438                UserHandle.getCallingUserId());
10439        if (pae == null) {
10440            return null;
10441        }
10442        synchronized (pae) {
10443            while (!pae.haveResult) {
10444                try {
10445                    pae.wait();
10446                } catch (InterruptedException e) {
10447                }
10448            }
10449            if (pae.result != null) {
10450                pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
10451            }
10452        }
10453        synchronized (this) {
10454            mPendingAssistExtras.remove(pae);
10455            mHandler.removeCallbacks(pae);
10456        }
10457        return pae.extras;
10458    }
10459
10460    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
10461            int userHandle) {
10462        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
10463                "getAssistContextExtras()");
10464        PendingAssistExtras pae;
10465        Bundle extras = new Bundle();
10466        synchronized (this) {
10467            ActivityRecord activity = getFocusedStack().mResumedActivity;
10468            if (activity == null) {
10469                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
10470                return null;
10471            }
10472            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
10473            if (activity.app == null || activity.app.thread == null) {
10474                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
10475                return null;
10476            }
10477            if (activity.app.pid == Binder.getCallingPid()) {
10478                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
10479                return null;
10480            }
10481            pae = new PendingAssistExtras(activity, extras, intent, hint, userHandle);
10482            try {
10483                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
10484                        requestType);
10485                mPendingAssistExtras.add(pae);
10486                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
10487            } catch (RemoteException e) {
10488                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
10489                return null;
10490            }
10491            return pae;
10492        }
10493    }
10494
10495    public void reportAssistContextExtras(IBinder token, Bundle extras) {
10496        PendingAssistExtras pae = (PendingAssistExtras)token;
10497        synchronized (pae) {
10498            pae.result = extras;
10499            pae.haveResult = true;
10500            pae.notifyAll();
10501            if (pae.intent == null) {
10502                // Caller is just waiting for the result.
10503                return;
10504            }
10505        }
10506
10507        // We are now ready to launch the assist activity.
10508        synchronized (this) {
10509            boolean exists = mPendingAssistExtras.remove(pae);
10510            mHandler.removeCallbacks(pae);
10511            if (!exists) {
10512                // Timed out.
10513                return;
10514            }
10515        }
10516        pae.intent.replaceExtras(extras);
10517        if (pae.hint != null) {
10518            pae.intent.putExtra(pae.hint, true);
10519        }
10520        pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10521                | Intent.FLAG_ACTIVITY_SINGLE_TOP
10522                | Intent.FLAG_ACTIVITY_CLEAR_TOP);
10523        closeSystemDialogs("assist");
10524        try {
10525            mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
10526        } catch (ActivityNotFoundException e) {
10527            Slog.w(TAG, "No activity to handle assist action.", e);
10528        }
10529    }
10530
10531    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle) {
10532        return enqueueAssistContext(requestType, intent, hint, userHandle) != null;
10533    }
10534
10535    public void registerProcessObserver(IProcessObserver observer) {
10536        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10537                "registerProcessObserver()");
10538        synchronized (this) {
10539            mProcessObservers.register(observer);
10540        }
10541    }
10542
10543    @Override
10544    public void unregisterProcessObserver(IProcessObserver observer) {
10545        synchronized (this) {
10546            mProcessObservers.unregister(observer);
10547        }
10548    }
10549
10550    @Override
10551    public boolean convertFromTranslucent(IBinder token) {
10552        final long origId = Binder.clearCallingIdentity();
10553        try {
10554            synchronized (this) {
10555                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10556                if (r == null) {
10557                    return false;
10558                }
10559                final boolean translucentChanged = r.changeWindowTranslucency(true);
10560                if (translucentChanged) {
10561                    r.task.stack.releaseBackgroundResources();
10562                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10563                }
10564                mWindowManager.setAppFullscreen(token, true);
10565                return translucentChanged;
10566            }
10567        } finally {
10568            Binder.restoreCallingIdentity(origId);
10569        }
10570    }
10571
10572    @Override
10573    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
10574        final long origId = Binder.clearCallingIdentity();
10575        try {
10576            synchronized (this) {
10577                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10578                if (r == null) {
10579                    return false;
10580                }
10581                int index = r.task.mActivities.lastIndexOf(r);
10582                if (index > 0) {
10583                    ActivityRecord under = r.task.mActivities.get(index - 1);
10584                    under.returningOptions = options;
10585                }
10586                final boolean translucentChanged = r.changeWindowTranslucency(false);
10587                if (translucentChanged) {
10588                    r.task.stack.convertToTranslucent(r);
10589                }
10590                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10591                mWindowManager.setAppFullscreen(token, false);
10592                return translucentChanged;
10593            }
10594        } finally {
10595            Binder.restoreCallingIdentity(origId);
10596        }
10597    }
10598
10599    @Override
10600    public boolean requestVisibleBehind(IBinder token, boolean visible) {
10601        final long origId = Binder.clearCallingIdentity();
10602        try {
10603            synchronized (this) {
10604                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10605                if (r != null) {
10606                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
10607                }
10608            }
10609            return false;
10610        } finally {
10611            Binder.restoreCallingIdentity(origId);
10612        }
10613    }
10614
10615    @Override
10616    public boolean isBackgroundVisibleBehind(IBinder token) {
10617        final long origId = Binder.clearCallingIdentity();
10618        try {
10619            synchronized (this) {
10620                final ActivityStack stack = ActivityRecord.getStackLocked(token);
10621                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
10622                if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG,
10623                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
10624                return visible;
10625            }
10626        } finally {
10627            Binder.restoreCallingIdentity(origId);
10628        }
10629    }
10630
10631    @Override
10632    public ActivityOptions getActivityOptions(IBinder token) {
10633        final long origId = Binder.clearCallingIdentity();
10634        try {
10635            synchronized (this) {
10636                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10637                if (r != null) {
10638                    final ActivityOptions activityOptions = r.pendingOptions;
10639                    r.pendingOptions = null;
10640                    return activityOptions;
10641                }
10642                return null;
10643            }
10644        } finally {
10645            Binder.restoreCallingIdentity(origId);
10646        }
10647    }
10648
10649    @Override
10650    public void setImmersive(IBinder token, boolean immersive) {
10651        synchronized(this) {
10652            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10653            if (r == null) {
10654                throw new IllegalArgumentException();
10655            }
10656            r.immersive = immersive;
10657
10658            // update associated state if we're frontmost
10659            if (r == mFocusedActivity) {
10660                if (DEBUG_IMMERSIVE) {
10661                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
10662                }
10663                applyUpdateLockStateLocked(r);
10664            }
10665        }
10666    }
10667
10668    @Override
10669    public boolean isImmersive(IBinder token) {
10670        synchronized (this) {
10671            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10672            if (r == null) {
10673                throw new IllegalArgumentException();
10674            }
10675            return r.immersive;
10676        }
10677    }
10678
10679    public boolean isTopActivityImmersive() {
10680        enforceNotIsolatedCaller("startActivity");
10681        synchronized (this) {
10682            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
10683            return (r != null) ? r.immersive : false;
10684        }
10685    }
10686
10687    @Override
10688    public boolean isTopOfTask(IBinder token) {
10689        synchronized (this) {
10690            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10691            if (r == null) {
10692                throw new IllegalArgumentException();
10693            }
10694            return r.task.getTopActivity() == r;
10695        }
10696    }
10697
10698    public final void enterSafeMode() {
10699        synchronized(this) {
10700            // It only makes sense to do this before the system is ready
10701            // and started launching other packages.
10702            if (!mSystemReady) {
10703                try {
10704                    AppGlobals.getPackageManager().enterSafeMode();
10705                } catch (RemoteException e) {
10706                }
10707            }
10708
10709            mSafeMode = true;
10710        }
10711    }
10712
10713    public final void showSafeModeOverlay() {
10714        View v = LayoutInflater.from(mContext).inflate(
10715                com.android.internal.R.layout.safe_mode, null);
10716        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
10717        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
10718        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
10719        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
10720        lp.gravity = Gravity.BOTTOM | Gravity.START;
10721        lp.format = v.getBackground().getOpacity();
10722        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
10723                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
10724        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
10725        ((WindowManager)mContext.getSystemService(
10726                Context.WINDOW_SERVICE)).addView(v, lp);
10727    }
10728
10729    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
10730        if (!(sender instanceof PendingIntentRecord)) {
10731            return;
10732        }
10733        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10734        synchronized (stats) {
10735            if (mBatteryStatsService.isOnBattery()) {
10736                mBatteryStatsService.enforceCallingPermission();
10737                PendingIntentRecord rec = (PendingIntentRecord)sender;
10738                int MY_UID = Binder.getCallingUid();
10739                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
10740                BatteryStatsImpl.Uid.Pkg pkg =
10741                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
10742                            sourcePkg != null ? sourcePkg : rec.key.packageName);
10743                pkg.incWakeupsLocked();
10744            }
10745        }
10746    }
10747
10748    public boolean killPids(int[] pids, String pReason, boolean secure) {
10749        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10750            throw new SecurityException("killPids only available to the system");
10751        }
10752        String reason = (pReason == null) ? "Unknown" : pReason;
10753        // XXX Note: don't acquire main activity lock here, because the window
10754        // manager calls in with its locks held.
10755
10756        boolean killed = false;
10757        synchronized (mPidsSelfLocked) {
10758            int[] types = new int[pids.length];
10759            int worstType = 0;
10760            for (int i=0; i<pids.length; i++) {
10761                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10762                if (proc != null) {
10763                    int type = proc.setAdj;
10764                    types[i] = type;
10765                    if (type > worstType) {
10766                        worstType = type;
10767                    }
10768                }
10769            }
10770
10771            // If the worst oom_adj is somewhere in the cached proc LRU range,
10772            // then constrain it so we will kill all cached procs.
10773            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
10774                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
10775                worstType = ProcessList.CACHED_APP_MIN_ADJ;
10776            }
10777
10778            // If this is not a secure call, don't let it kill processes that
10779            // are important.
10780            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
10781                worstType = ProcessList.SERVICE_ADJ;
10782            }
10783
10784            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
10785            for (int i=0; i<pids.length; i++) {
10786                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10787                if (proc == null) {
10788                    continue;
10789                }
10790                int adj = proc.setAdj;
10791                if (adj >= worstType && !proc.killedByAm) {
10792                    proc.kill(reason, true);
10793                    killed = true;
10794                }
10795            }
10796        }
10797        return killed;
10798    }
10799
10800    @Override
10801    public void killUid(int uid, String reason) {
10802        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10803            throw new SecurityException("killUid only available to the system");
10804        }
10805        synchronized (this) {
10806            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
10807                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
10808                    reason != null ? reason : "kill uid");
10809        }
10810    }
10811
10812    @Override
10813    public boolean killProcessesBelowForeground(String reason) {
10814        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10815            throw new SecurityException("killProcessesBelowForeground() only available to system");
10816        }
10817
10818        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
10819    }
10820
10821    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
10822        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10823            throw new SecurityException("killProcessesBelowAdj() only available to system");
10824        }
10825
10826        boolean killed = false;
10827        synchronized (mPidsSelfLocked) {
10828            final int size = mPidsSelfLocked.size();
10829            for (int i = 0; i < size; i++) {
10830                final int pid = mPidsSelfLocked.keyAt(i);
10831                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10832                if (proc == null) continue;
10833
10834                final int adj = proc.setAdj;
10835                if (adj > belowAdj && !proc.killedByAm) {
10836                    proc.kill(reason, true);
10837                    killed = true;
10838                }
10839            }
10840        }
10841        return killed;
10842    }
10843
10844    @Override
10845    public void hang(final IBinder who, boolean allowRestart) {
10846        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10847                != PackageManager.PERMISSION_GRANTED) {
10848            throw new SecurityException("Requires permission "
10849                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10850        }
10851
10852        final IBinder.DeathRecipient death = new DeathRecipient() {
10853            @Override
10854            public void binderDied() {
10855                synchronized (this) {
10856                    notifyAll();
10857                }
10858            }
10859        };
10860
10861        try {
10862            who.linkToDeath(death, 0);
10863        } catch (RemoteException e) {
10864            Slog.w(TAG, "hang: given caller IBinder is already dead.");
10865            return;
10866        }
10867
10868        synchronized (this) {
10869            Watchdog.getInstance().setAllowRestart(allowRestart);
10870            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
10871            synchronized (death) {
10872                while (who.isBinderAlive()) {
10873                    try {
10874                        death.wait();
10875                    } catch (InterruptedException e) {
10876                    }
10877                }
10878            }
10879            Watchdog.getInstance().setAllowRestart(true);
10880        }
10881    }
10882
10883    @Override
10884    public void restart() {
10885        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10886                != PackageManager.PERMISSION_GRANTED) {
10887            throw new SecurityException("Requires permission "
10888                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10889        }
10890
10891        Log.i(TAG, "Sending shutdown broadcast...");
10892
10893        BroadcastReceiver br = new BroadcastReceiver() {
10894            @Override public void onReceive(Context context, Intent intent) {
10895                // Now the broadcast is done, finish up the low-level shutdown.
10896                Log.i(TAG, "Shutting down activity manager...");
10897                shutdown(10000);
10898                Log.i(TAG, "Shutdown complete, restarting!");
10899                Process.killProcess(Process.myPid());
10900                System.exit(10);
10901            }
10902        };
10903
10904        // First send the high-level shut down broadcast.
10905        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
10906        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
10907        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
10908        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
10909        mContext.sendOrderedBroadcastAsUser(intent,
10910                UserHandle.ALL, null, br, mHandler, 0, null, null);
10911        */
10912        br.onReceive(mContext, intent);
10913    }
10914
10915    private long getLowRamTimeSinceIdle(long now) {
10916        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
10917    }
10918
10919    @Override
10920    public void performIdleMaintenance() {
10921        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10922                != PackageManager.PERMISSION_GRANTED) {
10923            throw new SecurityException("Requires permission "
10924                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10925        }
10926
10927        synchronized (this) {
10928            final long now = SystemClock.uptimeMillis();
10929            final long timeSinceLastIdle = now - mLastIdleTime;
10930            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
10931            mLastIdleTime = now;
10932            mLowRamTimeSinceLastIdle = 0;
10933            if (mLowRamStartTime != 0) {
10934                mLowRamStartTime = now;
10935            }
10936
10937            StringBuilder sb = new StringBuilder(128);
10938            sb.append("Idle maintenance over ");
10939            TimeUtils.formatDuration(timeSinceLastIdle, sb);
10940            sb.append(" low RAM for ");
10941            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
10942            Slog.i(TAG, sb.toString());
10943
10944            // If at least 1/3 of our time since the last idle period has been spent
10945            // with RAM low, then we want to kill processes.
10946            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
10947
10948            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
10949                ProcessRecord proc = mLruProcesses.get(i);
10950                if (proc.notCachedSinceIdle) {
10951                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
10952                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
10953                        if (doKilling && proc.initialIdlePss != 0
10954                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
10955                            sb = new StringBuilder(128);
10956                            sb.append("Kill");
10957                            sb.append(proc.processName);
10958                            sb.append(" in idle maint: pss=");
10959                            sb.append(proc.lastPss);
10960                            sb.append(", initialPss=");
10961                            sb.append(proc.initialIdlePss);
10962                            sb.append(", period=");
10963                            TimeUtils.formatDuration(timeSinceLastIdle, sb);
10964                            sb.append(", lowRamPeriod=");
10965                            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
10966                            Slog.wtfQuiet(TAG, sb.toString());
10967                            proc.kill("idle maint (pss " + proc.lastPss
10968                                    + " from " + proc.initialIdlePss + ")", true);
10969                        }
10970                    }
10971                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
10972                    proc.notCachedSinceIdle = true;
10973                    proc.initialIdlePss = 0;
10974                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
10975                            mTestPssMode, isSleeping(), now);
10976                }
10977            }
10978
10979            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
10980            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
10981        }
10982    }
10983
10984    private void retrieveSettings() {
10985        final ContentResolver resolver = mContext.getContentResolver();
10986        String debugApp = Settings.Global.getString(
10987            resolver, Settings.Global.DEBUG_APP);
10988        boolean waitForDebugger = Settings.Global.getInt(
10989            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
10990        boolean alwaysFinishActivities = Settings.Global.getInt(
10991            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
10992        boolean forceRtl = Settings.Global.getInt(
10993                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
10994        // Transfer any global setting for forcing RTL layout, into a System Property
10995        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
10996
10997        Configuration configuration = new Configuration();
10998        Settings.System.getConfiguration(resolver, configuration);
10999        if (forceRtl) {
11000            // This will take care of setting the correct layout direction flags
11001            configuration.setLayoutDirection(configuration.locale);
11002        }
11003
11004        synchronized (this) {
11005            mDebugApp = mOrigDebugApp = debugApp;
11006            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
11007            mAlwaysFinishActivities = alwaysFinishActivities;
11008            // This happens before any activities are started, so we can
11009            // change mConfiguration in-place.
11010            updateConfigurationLocked(configuration, null, false, true);
11011            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
11012        }
11013    }
11014
11015    /** Loads resources after the current configuration has been set. */
11016    private void loadResourcesOnSystemReady() {
11017        final Resources res = mContext.getResources();
11018        mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
11019        mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
11020        mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
11021    }
11022
11023    public boolean testIsSystemReady() {
11024        // no need to synchronize(this) just to read & return the value
11025        return mSystemReady;
11026    }
11027
11028    private static File getCalledPreBootReceiversFile() {
11029        File dataDir = Environment.getDataDirectory();
11030        File systemDir = new File(dataDir, "system");
11031        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
11032        return fname;
11033    }
11034
11035    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
11036        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
11037        File file = getCalledPreBootReceiversFile();
11038        FileInputStream fis = null;
11039        try {
11040            fis = new FileInputStream(file);
11041            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
11042            int fvers = dis.readInt();
11043            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
11044                String vers = dis.readUTF();
11045                String codename = dis.readUTF();
11046                String build = dis.readUTF();
11047                if (android.os.Build.VERSION.RELEASE.equals(vers)
11048                        && android.os.Build.VERSION.CODENAME.equals(codename)
11049                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
11050                    int num = dis.readInt();
11051                    while (num > 0) {
11052                        num--;
11053                        String pkg = dis.readUTF();
11054                        String cls = dis.readUTF();
11055                        lastDoneReceivers.add(new ComponentName(pkg, cls));
11056                    }
11057                }
11058            }
11059        } catch (FileNotFoundException e) {
11060        } catch (IOException e) {
11061            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
11062        } finally {
11063            if (fis != null) {
11064                try {
11065                    fis.close();
11066                } catch (IOException e) {
11067                }
11068            }
11069        }
11070        return lastDoneReceivers;
11071    }
11072
11073    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
11074        File file = getCalledPreBootReceiversFile();
11075        FileOutputStream fos = null;
11076        DataOutputStream dos = null;
11077        try {
11078            fos = new FileOutputStream(file);
11079            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
11080            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
11081            dos.writeUTF(android.os.Build.VERSION.RELEASE);
11082            dos.writeUTF(android.os.Build.VERSION.CODENAME);
11083            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
11084            dos.writeInt(list.size());
11085            for (int i=0; i<list.size(); i++) {
11086                dos.writeUTF(list.get(i).getPackageName());
11087                dos.writeUTF(list.get(i).getClassName());
11088            }
11089        } catch (IOException e) {
11090            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
11091            file.delete();
11092        } finally {
11093            FileUtils.sync(fos);
11094            if (dos != null) {
11095                try {
11096                    dos.close();
11097                } catch (IOException e) {
11098                    // TODO Auto-generated catch block
11099                    e.printStackTrace();
11100                }
11101            }
11102        }
11103    }
11104
11105    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
11106            ArrayList<ComponentName> doneReceivers, int userId) {
11107        boolean waitingUpdate = false;
11108        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
11109        List<ResolveInfo> ris = null;
11110        try {
11111            ris = AppGlobals.getPackageManager().queryIntentReceivers(
11112                    intent, null, 0, userId);
11113        } catch (RemoteException e) {
11114        }
11115        if (ris != null) {
11116            for (int i=ris.size()-1; i>=0; i--) {
11117                if ((ris.get(i).activityInfo.applicationInfo.flags
11118                        &ApplicationInfo.FLAG_SYSTEM) == 0) {
11119                    ris.remove(i);
11120                }
11121            }
11122            intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
11123
11124            // For User 0, load the version number. When delivering to a new user, deliver
11125            // to all receivers.
11126            if (userId == UserHandle.USER_OWNER) {
11127                ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
11128                for (int i=0; i<ris.size(); i++) {
11129                    ActivityInfo ai = ris.get(i).activityInfo;
11130                    ComponentName comp = new ComponentName(ai.packageName, ai.name);
11131                    if (lastDoneReceivers.contains(comp)) {
11132                        // We already did the pre boot receiver for this app with the current
11133                        // platform version, so don't do it again...
11134                        ris.remove(i);
11135                        i--;
11136                        // ...however, do keep it as one that has been done, so we don't
11137                        // forget about it when rewriting the file of last done receivers.
11138                        doneReceivers.add(comp);
11139                    }
11140                }
11141            }
11142
11143            // If primary user, send broadcast to all available users, else just to userId
11144            final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
11145                    : new int[] { userId };
11146            for (int i = 0; i < ris.size(); i++) {
11147                ActivityInfo ai = ris.get(i).activityInfo;
11148                ComponentName comp = new ComponentName(ai.packageName, ai.name);
11149                doneReceivers.add(comp);
11150                intent.setComponent(comp);
11151                for (int j=0; j<users.length; j++) {
11152                    IIntentReceiver finisher = null;
11153                    // On last receiver and user, set up a completion callback
11154                    if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) {
11155                        finisher = new IIntentReceiver.Stub() {
11156                            public void performReceive(Intent intent, int resultCode,
11157                                    String data, Bundle extras, boolean ordered,
11158                                    boolean sticky, int sendingUser) {
11159                                // The raw IIntentReceiver interface is called
11160                                // with the AM lock held, so redispatch to
11161                                // execute our code without the lock.
11162                                mHandler.post(onFinishCallback);
11163                            }
11164                        };
11165                    }
11166                    Slog.i(TAG, "Sending system update to " + intent.getComponent()
11167                            + " for user " + users[j]);
11168                    broadcastIntentLocked(null, null, intent, null, finisher,
11169                            0, null, null, null, AppOpsManager.OP_NONE,
11170                            true, false, MY_PID, Process.SYSTEM_UID,
11171                            users[j]);
11172                    if (finisher != null) {
11173                        waitingUpdate = true;
11174                    }
11175                }
11176            }
11177        }
11178
11179        return waitingUpdate;
11180    }
11181
11182    public void systemReady(final Runnable goingCallback) {
11183        synchronized(this) {
11184            if (mSystemReady) {
11185                // If we're done calling all the receivers, run the next "boot phase" passed in
11186                // by the SystemServer
11187                if (goingCallback != null) {
11188                    goingCallback.run();
11189                }
11190                return;
11191            }
11192
11193            // Make sure we have the current profile info, since it is needed for
11194            // security checks.
11195            updateCurrentProfileIdsLocked();
11196
11197            if (mRecentTasks == null) {
11198                mRecentTasks = mTaskPersister.restoreTasksLocked();
11199                mTaskPersister.restoreTasksFromOtherDeviceLocked();
11200                cleanupRecentTasksLocked(UserHandle.USER_ALL);
11201                mTaskPersister.startPersisting();
11202            }
11203
11204            // Check to see if there are any update receivers to run.
11205            if (!mDidUpdate) {
11206                if (mWaitingUpdate) {
11207                    return;
11208                }
11209                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
11210                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
11211                    public void run() {
11212                        synchronized (ActivityManagerService.this) {
11213                            mDidUpdate = true;
11214                        }
11215                        writeLastDonePreBootReceivers(doneReceivers);
11216                        showBootMessage(mContext.getText(R.string.android_upgrading_complete),
11217                                false);
11218                        systemReady(goingCallback);
11219                    }
11220                }, doneReceivers, UserHandle.USER_OWNER);
11221
11222                if (mWaitingUpdate) {
11223                    return;
11224                }
11225                mDidUpdate = true;
11226            }
11227
11228            mAppOpsService.systemReady();
11229            mSystemReady = true;
11230        }
11231
11232        ArrayList<ProcessRecord> procsToKill = null;
11233        synchronized(mPidsSelfLocked) {
11234            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
11235                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
11236                if (!isAllowedWhileBooting(proc.info)){
11237                    if (procsToKill == null) {
11238                        procsToKill = new ArrayList<ProcessRecord>();
11239                    }
11240                    procsToKill.add(proc);
11241                }
11242            }
11243        }
11244
11245        synchronized(this) {
11246            if (procsToKill != null) {
11247                for (int i=procsToKill.size()-1; i>=0; i--) {
11248                    ProcessRecord proc = procsToKill.get(i);
11249                    Slog.i(TAG, "Removing system update proc: " + proc);
11250                    removeProcessLocked(proc, true, false, "system update done");
11251                }
11252            }
11253
11254            // Now that we have cleaned up any update processes, we
11255            // are ready to start launching real processes and know that
11256            // we won't trample on them any more.
11257            mProcessesReady = true;
11258        }
11259
11260        Slog.i(TAG, "System now ready");
11261        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
11262            SystemClock.uptimeMillis());
11263
11264        synchronized(this) {
11265            // Make sure we have no pre-ready processes sitting around.
11266
11267            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11268                ResolveInfo ri = mContext.getPackageManager()
11269                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
11270                                STOCK_PM_FLAGS);
11271                CharSequence errorMsg = null;
11272                if (ri != null) {
11273                    ActivityInfo ai = ri.activityInfo;
11274                    ApplicationInfo app = ai.applicationInfo;
11275                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
11276                        mTopAction = Intent.ACTION_FACTORY_TEST;
11277                        mTopData = null;
11278                        mTopComponent = new ComponentName(app.packageName,
11279                                ai.name);
11280                    } else {
11281                        errorMsg = mContext.getResources().getText(
11282                                com.android.internal.R.string.factorytest_not_system);
11283                    }
11284                } else {
11285                    errorMsg = mContext.getResources().getText(
11286                            com.android.internal.R.string.factorytest_no_action);
11287                }
11288                if (errorMsg != null) {
11289                    mTopAction = null;
11290                    mTopData = null;
11291                    mTopComponent = null;
11292                    Message msg = Message.obtain();
11293                    msg.what = SHOW_FACTORY_ERROR_MSG;
11294                    msg.getData().putCharSequence("msg", errorMsg);
11295                    mHandler.sendMessage(msg);
11296                }
11297            }
11298        }
11299
11300        retrieveSettings();
11301        loadResourcesOnSystemReady();
11302
11303        synchronized (this) {
11304            readGrantedUriPermissionsLocked();
11305        }
11306
11307        if (goingCallback != null) goingCallback.run();
11308
11309        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
11310                Integer.toString(mCurrentUserId), mCurrentUserId);
11311        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
11312                Integer.toString(mCurrentUserId), mCurrentUserId);
11313        mSystemServiceManager.startUser(mCurrentUserId);
11314
11315        synchronized (this) {
11316            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11317                try {
11318                    List apps = AppGlobals.getPackageManager().
11319                        getPersistentApplications(STOCK_PM_FLAGS);
11320                    if (apps != null) {
11321                        int N = apps.size();
11322                        int i;
11323                        for (i=0; i<N; i++) {
11324                            ApplicationInfo info
11325                                = (ApplicationInfo)apps.get(i);
11326                            if (info != null &&
11327                                    !info.packageName.equals("android")) {
11328                                addAppLocked(info, false, null /* ABI override */);
11329                            }
11330                        }
11331                    }
11332                } catch (RemoteException ex) {
11333                    // pm is in same process, this will never happen.
11334                }
11335            }
11336
11337            // Start up initial activity.
11338            mBooting = true;
11339            startHomeActivityLocked(mCurrentUserId);
11340
11341            try {
11342                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
11343                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
11344                            + " data partition or your device will be unstable.");
11345                    mHandler.obtainMessage(SHOW_UID_ERROR_MSG).sendToTarget();
11346                }
11347            } catch (RemoteException e) {
11348            }
11349
11350            if (!Build.isFingerprintConsistent()) {
11351                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
11352                mHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_MSG).sendToTarget();
11353            }
11354
11355            long ident = Binder.clearCallingIdentity();
11356            try {
11357                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
11358                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
11359                        | Intent.FLAG_RECEIVER_FOREGROUND);
11360                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11361                broadcastIntentLocked(null, null, intent,
11362                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
11363                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
11364                intent = new Intent(Intent.ACTION_USER_STARTING);
11365                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11366                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11367                broadcastIntentLocked(null, null, intent,
11368                        null, new IIntentReceiver.Stub() {
11369                            @Override
11370                            public void performReceive(Intent intent, int resultCode, String data,
11371                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
11372                                    throws RemoteException {
11373                            }
11374                        }, 0, null, null,
11375                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
11376                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
11377            } catch (Throwable t) {
11378                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
11379            } finally {
11380                Binder.restoreCallingIdentity(ident);
11381            }
11382            mStackSupervisor.resumeTopActivitiesLocked();
11383            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
11384        }
11385    }
11386
11387    private boolean makeAppCrashingLocked(ProcessRecord app,
11388            String shortMsg, String longMsg, String stackTrace) {
11389        app.crashing = true;
11390        app.crashingReport = generateProcessError(app,
11391                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
11392        startAppProblemLocked(app);
11393        app.stopFreezingAllLocked();
11394        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
11395    }
11396
11397    private void makeAppNotRespondingLocked(ProcessRecord app,
11398            String activity, String shortMsg, String longMsg) {
11399        app.notResponding = true;
11400        app.notRespondingReport = generateProcessError(app,
11401                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
11402                activity, shortMsg, longMsg, null);
11403        startAppProblemLocked(app);
11404        app.stopFreezingAllLocked();
11405    }
11406
11407    /**
11408     * Generate a process error record, suitable for attachment to a ProcessRecord.
11409     *
11410     * @param app The ProcessRecord in which the error occurred.
11411     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
11412     *                      ActivityManager.AppErrorStateInfo
11413     * @param activity The activity associated with the crash, if known.
11414     * @param shortMsg Short message describing the crash.
11415     * @param longMsg Long message describing the crash.
11416     * @param stackTrace Full crash stack trace, may be null.
11417     *
11418     * @return Returns a fully-formed AppErrorStateInfo record.
11419     */
11420    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
11421            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
11422        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
11423
11424        report.condition = condition;
11425        report.processName = app.processName;
11426        report.pid = app.pid;
11427        report.uid = app.info.uid;
11428        report.tag = activity;
11429        report.shortMsg = shortMsg;
11430        report.longMsg = longMsg;
11431        report.stackTrace = stackTrace;
11432
11433        return report;
11434    }
11435
11436    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
11437        synchronized (this) {
11438            app.crashing = false;
11439            app.crashingReport = null;
11440            app.notResponding = false;
11441            app.notRespondingReport = null;
11442            if (app.anrDialog == fromDialog) {
11443                app.anrDialog = null;
11444            }
11445            if (app.waitDialog == fromDialog) {
11446                app.waitDialog = null;
11447            }
11448            if (app.pid > 0 && app.pid != MY_PID) {
11449                handleAppCrashLocked(app, null, null, null);
11450                app.kill("user request after error", true);
11451            }
11452        }
11453    }
11454
11455    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
11456            String stackTrace) {
11457        long now = SystemClock.uptimeMillis();
11458
11459        Long crashTime;
11460        if (!app.isolated) {
11461            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
11462        } else {
11463            crashTime = null;
11464        }
11465        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
11466            // This process loses!
11467            Slog.w(TAG, "Process " + app.info.processName
11468                    + " has crashed too many times: killing!");
11469            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
11470                    app.userId, app.info.processName, app.uid);
11471            mStackSupervisor.handleAppCrashLocked(app);
11472            if (!app.persistent) {
11473                // We don't want to start this process again until the user
11474                // explicitly does so...  but for persistent process, we really
11475                // need to keep it running.  If a persistent process is actually
11476                // repeatedly crashing, then badness for everyone.
11477                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
11478                        app.info.processName);
11479                if (!app.isolated) {
11480                    // XXX We don't have a way to mark isolated processes
11481                    // as bad, since they don't have a peristent identity.
11482                    mBadProcesses.put(app.info.processName, app.uid,
11483                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
11484                    mProcessCrashTimes.remove(app.info.processName, app.uid);
11485                }
11486                app.bad = true;
11487                app.removed = true;
11488                // Don't let services in this process be restarted and potentially
11489                // annoy the user repeatedly.  Unless it is persistent, since those
11490                // processes run critical code.
11491                removeProcessLocked(app, false, false, "crash");
11492                mStackSupervisor.resumeTopActivitiesLocked();
11493                return false;
11494            }
11495            mStackSupervisor.resumeTopActivitiesLocked();
11496        } else {
11497            mStackSupervisor.finishTopRunningActivityLocked(app);
11498        }
11499
11500        // Bump up the crash count of any services currently running in the proc.
11501        for (int i=app.services.size()-1; i>=0; i--) {
11502            // Any services running in the application need to be placed
11503            // back in the pending list.
11504            ServiceRecord sr = app.services.valueAt(i);
11505            sr.crashCount++;
11506        }
11507
11508        // If the crashing process is what we consider to be the "home process" and it has been
11509        // replaced by a third-party app, clear the package preferred activities from packages
11510        // with a home activity running in the process to prevent a repeatedly crashing app
11511        // from blocking the user to manually clear the list.
11512        final ArrayList<ActivityRecord> activities = app.activities;
11513        if (app == mHomeProcess && activities.size() > 0
11514                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
11515            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
11516                final ActivityRecord r = activities.get(activityNdx);
11517                if (r.isHomeActivity()) {
11518                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
11519                    try {
11520                        ActivityThread.getPackageManager()
11521                                .clearPackagePreferredActivities(r.packageName);
11522                    } catch (RemoteException c) {
11523                        // pm is in same process, this will never happen.
11524                    }
11525                }
11526            }
11527        }
11528
11529        if (!app.isolated) {
11530            // XXX Can't keep track of crash times for isolated processes,
11531            // because they don't have a perisistent identity.
11532            mProcessCrashTimes.put(app.info.processName, app.uid, now);
11533        }
11534
11535        if (app.crashHandler != null) mHandler.post(app.crashHandler);
11536        return true;
11537    }
11538
11539    void startAppProblemLocked(ProcessRecord app) {
11540        // If this app is not running under the current user, then we
11541        // can't give it a report button because that would require
11542        // launching the report UI under a different user.
11543        app.errorReportReceiver = null;
11544
11545        for (int userId : mCurrentProfileIds) {
11546            if (app.userId == userId) {
11547                app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
11548                        mContext, app.info.packageName, app.info.flags);
11549            }
11550        }
11551        skipCurrentReceiverLocked(app);
11552    }
11553
11554    void skipCurrentReceiverLocked(ProcessRecord app) {
11555        for (BroadcastQueue queue : mBroadcastQueues) {
11556            queue.skipCurrentReceiverLocked(app);
11557        }
11558    }
11559
11560    /**
11561     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
11562     * The application process will exit immediately after this call returns.
11563     * @param app object of the crashing app, null for the system server
11564     * @param crashInfo describing the exception
11565     */
11566    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
11567        ProcessRecord r = findAppProcess(app, "Crash");
11568        final String processName = app == null ? "system_server"
11569                : (r == null ? "unknown" : r.processName);
11570
11571        handleApplicationCrashInner("crash", r, processName, crashInfo);
11572    }
11573
11574    /* Native crash reporting uses this inner version because it needs to be somewhat
11575     * decoupled from the AM-managed cleanup lifecycle
11576     */
11577    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
11578            ApplicationErrorReport.CrashInfo crashInfo) {
11579        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
11580                UserHandle.getUserId(Binder.getCallingUid()), processName,
11581                r == null ? -1 : r.info.flags,
11582                crashInfo.exceptionClassName,
11583                crashInfo.exceptionMessage,
11584                crashInfo.throwFileName,
11585                crashInfo.throwLineNumber);
11586
11587        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
11588
11589        crashApplication(r, crashInfo);
11590    }
11591
11592    public void handleApplicationStrictModeViolation(
11593            IBinder app,
11594            int violationMask,
11595            StrictMode.ViolationInfo info) {
11596        ProcessRecord r = findAppProcess(app, "StrictMode");
11597        if (r == null) {
11598            return;
11599        }
11600
11601        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
11602            Integer stackFingerprint = info.hashCode();
11603            boolean logIt = true;
11604            synchronized (mAlreadyLoggedViolatedStacks) {
11605                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
11606                    logIt = false;
11607                    // TODO: sub-sample into EventLog for these, with
11608                    // the info.durationMillis?  Then we'd get
11609                    // the relative pain numbers, without logging all
11610                    // the stack traces repeatedly.  We'd want to do
11611                    // likewise in the client code, which also does
11612                    // dup suppression, before the Binder call.
11613                } else {
11614                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
11615                        mAlreadyLoggedViolatedStacks.clear();
11616                    }
11617                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
11618                }
11619            }
11620            if (logIt) {
11621                logStrictModeViolationToDropBox(r, info);
11622            }
11623        }
11624
11625        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
11626            AppErrorResult result = new AppErrorResult();
11627            synchronized (this) {
11628                final long origId = Binder.clearCallingIdentity();
11629
11630                Message msg = Message.obtain();
11631                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
11632                HashMap<String, Object> data = new HashMap<String, Object>();
11633                data.put("result", result);
11634                data.put("app", r);
11635                data.put("violationMask", violationMask);
11636                data.put("info", info);
11637                msg.obj = data;
11638                mHandler.sendMessage(msg);
11639
11640                Binder.restoreCallingIdentity(origId);
11641            }
11642            int res = result.get();
11643            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
11644        }
11645    }
11646
11647    // Depending on the policy in effect, there could be a bunch of
11648    // these in quick succession so we try to batch these together to
11649    // minimize disk writes, number of dropbox entries, and maximize
11650    // compression, by having more fewer, larger records.
11651    private void logStrictModeViolationToDropBox(
11652            ProcessRecord process,
11653            StrictMode.ViolationInfo info) {
11654        if (info == null) {
11655            return;
11656        }
11657        final boolean isSystemApp = process == null ||
11658                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
11659                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
11660        final String processName = process == null ? "unknown" : process.processName;
11661        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
11662        final DropBoxManager dbox = (DropBoxManager)
11663                mContext.getSystemService(Context.DROPBOX_SERVICE);
11664
11665        // Exit early if the dropbox isn't configured to accept this report type.
11666        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11667
11668        boolean bufferWasEmpty;
11669        boolean needsFlush;
11670        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
11671        synchronized (sb) {
11672            bufferWasEmpty = sb.length() == 0;
11673            appendDropBoxProcessHeaders(process, processName, sb);
11674            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11675            sb.append("System-App: ").append(isSystemApp).append("\n");
11676            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
11677            if (info.violationNumThisLoop != 0) {
11678                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
11679            }
11680            if (info.numAnimationsRunning != 0) {
11681                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
11682            }
11683            if (info.broadcastIntentAction != null) {
11684                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
11685            }
11686            if (info.durationMillis != -1) {
11687                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
11688            }
11689            if (info.numInstances != -1) {
11690                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
11691            }
11692            if (info.tags != null) {
11693                for (String tag : info.tags) {
11694                    sb.append("Span-Tag: ").append(tag).append("\n");
11695                }
11696            }
11697            sb.append("\n");
11698            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
11699                sb.append(info.crashInfo.stackTrace);
11700            }
11701            sb.append("\n");
11702
11703            // Only buffer up to ~64k.  Various logging bits truncate
11704            // things at 128k.
11705            needsFlush = (sb.length() > 64 * 1024);
11706        }
11707
11708        // Flush immediately if the buffer's grown too large, or this
11709        // is a non-system app.  Non-system apps are isolated with a
11710        // different tag & policy and not batched.
11711        //
11712        // Batching is useful during internal testing with
11713        // StrictMode settings turned up high.  Without batching,
11714        // thousands of separate files could be created on boot.
11715        if (!isSystemApp || needsFlush) {
11716            new Thread("Error dump: " + dropboxTag) {
11717                @Override
11718                public void run() {
11719                    String report;
11720                    synchronized (sb) {
11721                        report = sb.toString();
11722                        sb.delete(0, sb.length());
11723                        sb.trimToSize();
11724                    }
11725                    if (report.length() != 0) {
11726                        dbox.addText(dropboxTag, report);
11727                    }
11728                }
11729            }.start();
11730            return;
11731        }
11732
11733        // System app batching:
11734        if (!bufferWasEmpty) {
11735            // An existing dropbox-writing thread is outstanding, so
11736            // we don't need to start it up.  The existing thread will
11737            // catch the buffer appends we just did.
11738            return;
11739        }
11740
11741        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
11742        // (After this point, we shouldn't access AMS internal data structures.)
11743        new Thread("Error dump: " + dropboxTag) {
11744            @Override
11745            public void run() {
11746                // 5 second sleep to let stacks arrive and be batched together
11747                try {
11748                    Thread.sleep(5000);  // 5 seconds
11749                } catch (InterruptedException e) {}
11750
11751                String errorReport;
11752                synchronized (mStrictModeBuffer) {
11753                    errorReport = mStrictModeBuffer.toString();
11754                    if (errorReport.length() == 0) {
11755                        return;
11756                    }
11757                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
11758                    mStrictModeBuffer.trimToSize();
11759                }
11760                dbox.addText(dropboxTag, errorReport);
11761            }
11762        }.start();
11763    }
11764
11765    /**
11766     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
11767     * @param app object of the crashing app, null for the system server
11768     * @param tag reported by the caller
11769     * @param system whether this wtf is coming from the system
11770     * @param crashInfo describing the context of the error
11771     * @return true if the process should exit immediately (WTF is fatal)
11772     */
11773    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
11774            final ApplicationErrorReport.CrashInfo crashInfo) {
11775        final int callingUid = Binder.getCallingUid();
11776        final int callingPid = Binder.getCallingPid();
11777
11778        if (system) {
11779            // If this is coming from the system, we could very well have low-level
11780            // system locks held, so we want to do this all asynchronously.  And we
11781            // never want this to become fatal, so there is that too.
11782            mHandler.post(new Runnable() {
11783                @Override public void run() {
11784                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
11785                }
11786            });
11787            return false;
11788        }
11789
11790        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
11791                crashInfo);
11792
11793        if (r != null && r.pid != Process.myPid() &&
11794                Settings.Global.getInt(mContext.getContentResolver(),
11795                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
11796            crashApplication(r, crashInfo);
11797            return true;
11798        } else {
11799            return false;
11800        }
11801    }
11802
11803    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
11804            final ApplicationErrorReport.CrashInfo crashInfo) {
11805        final ProcessRecord r = findAppProcess(app, "WTF");
11806        final String processName = app == null ? "system_server"
11807                : (r == null ? "unknown" : r.processName);
11808
11809        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
11810                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
11811
11812        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
11813
11814        return r;
11815    }
11816
11817    /**
11818     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
11819     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
11820     */
11821    private ProcessRecord findAppProcess(IBinder app, String reason) {
11822        if (app == null) {
11823            return null;
11824        }
11825
11826        synchronized (this) {
11827            final int NP = mProcessNames.getMap().size();
11828            for (int ip=0; ip<NP; ip++) {
11829                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11830                final int NA = apps.size();
11831                for (int ia=0; ia<NA; ia++) {
11832                    ProcessRecord p = apps.valueAt(ia);
11833                    if (p.thread != null && p.thread.asBinder() == app) {
11834                        return p;
11835                    }
11836                }
11837            }
11838
11839            Slog.w(TAG, "Can't find mystery application for " + reason
11840                    + " from pid=" + Binder.getCallingPid()
11841                    + " uid=" + Binder.getCallingUid() + ": " + app);
11842            return null;
11843        }
11844    }
11845
11846    /**
11847     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
11848     * to append various headers to the dropbox log text.
11849     */
11850    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
11851            StringBuilder sb) {
11852        // Watchdog thread ends up invoking this function (with
11853        // a null ProcessRecord) to add the stack file to dropbox.
11854        // Do not acquire a lock on this (am) in such cases, as it
11855        // could cause a potential deadlock, if and when watchdog
11856        // is invoked due to unavailability of lock on am and it
11857        // would prevent watchdog from killing system_server.
11858        if (process == null) {
11859            sb.append("Process: ").append(processName).append("\n");
11860            return;
11861        }
11862        // Note: ProcessRecord 'process' is guarded by the service
11863        // instance.  (notably process.pkgList, which could otherwise change
11864        // concurrently during execution of this method)
11865        synchronized (this) {
11866            sb.append("Process: ").append(processName).append("\n");
11867            int flags = process.info.flags;
11868            IPackageManager pm = AppGlobals.getPackageManager();
11869            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
11870            for (int ip=0; ip<process.pkgList.size(); ip++) {
11871                String pkg = process.pkgList.keyAt(ip);
11872                sb.append("Package: ").append(pkg);
11873                try {
11874                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
11875                    if (pi != null) {
11876                        sb.append(" v").append(pi.versionCode);
11877                        if (pi.versionName != null) {
11878                            sb.append(" (").append(pi.versionName).append(")");
11879                        }
11880                    }
11881                } catch (RemoteException e) {
11882                    Slog.e(TAG, "Error getting package info: " + pkg, e);
11883                }
11884                sb.append("\n");
11885            }
11886        }
11887    }
11888
11889    private static String processClass(ProcessRecord process) {
11890        if (process == null || process.pid == MY_PID) {
11891            return "system_server";
11892        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
11893            return "system_app";
11894        } else {
11895            return "data_app";
11896        }
11897    }
11898
11899    /**
11900     * Write a description of an error (crash, WTF, ANR) to the drop box.
11901     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
11902     * @param process which caused the error, null means the system server
11903     * @param activity which triggered the error, null if unknown
11904     * @param parent activity related to the error, null if unknown
11905     * @param subject line related to the error, null if absent
11906     * @param report in long form describing the error, null if absent
11907     * @param logFile to include in the report, null if none
11908     * @param crashInfo giving an application stack trace, null if absent
11909     */
11910    public void addErrorToDropBox(String eventType,
11911            ProcessRecord process, String processName, ActivityRecord activity,
11912            ActivityRecord parent, String subject,
11913            final String report, final File logFile,
11914            final ApplicationErrorReport.CrashInfo crashInfo) {
11915        // NOTE -- this must never acquire the ActivityManagerService lock,
11916        // otherwise the watchdog may be prevented from resetting the system.
11917
11918        final String dropboxTag = processClass(process) + "_" + eventType;
11919        final DropBoxManager dbox = (DropBoxManager)
11920                mContext.getSystemService(Context.DROPBOX_SERVICE);
11921
11922        // Exit early if the dropbox isn't configured to accept this report type.
11923        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11924
11925        final StringBuilder sb = new StringBuilder(1024);
11926        appendDropBoxProcessHeaders(process, processName, sb);
11927        if (activity != null) {
11928            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
11929        }
11930        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
11931            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
11932        }
11933        if (parent != null && parent != activity) {
11934            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
11935        }
11936        if (subject != null) {
11937            sb.append("Subject: ").append(subject).append("\n");
11938        }
11939        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11940        if (Debug.isDebuggerConnected()) {
11941            sb.append("Debugger: Connected\n");
11942        }
11943        sb.append("\n");
11944
11945        // Do the rest in a worker thread to avoid blocking the caller on I/O
11946        // (After this point, we shouldn't access AMS internal data structures.)
11947        Thread worker = new Thread("Error dump: " + dropboxTag) {
11948            @Override
11949            public void run() {
11950                if (report != null) {
11951                    sb.append(report);
11952                }
11953                if (logFile != null) {
11954                    try {
11955                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
11956                                    "\n\n[[TRUNCATED]]"));
11957                    } catch (IOException e) {
11958                        Slog.e(TAG, "Error reading " + logFile, e);
11959                    }
11960                }
11961                if (crashInfo != null && crashInfo.stackTrace != null) {
11962                    sb.append(crashInfo.stackTrace);
11963                }
11964
11965                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
11966                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
11967                if (lines > 0) {
11968                    sb.append("\n");
11969
11970                    // Merge several logcat streams, and take the last N lines
11971                    InputStreamReader input = null;
11972                    try {
11973                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
11974                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
11975                                "-b", "crash",
11976                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
11977
11978                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
11979                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
11980                        input = new InputStreamReader(logcat.getInputStream());
11981
11982                        int num;
11983                        char[] buf = new char[8192];
11984                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
11985                    } catch (IOException e) {
11986                        Slog.e(TAG, "Error running logcat", e);
11987                    } finally {
11988                        if (input != null) try { input.close(); } catch (IOException e) {}
11989                    }
11990                }
11991
11992                dbox.addText(dropboxTag, sb.toString());
11993            }
11994        };
11995
11996        if (process == null) {
11997            // If process is null, we are being called from some internal code
11998            // and may be about to die -- run this synchronously.
11999            worker.run();
12000        } else {
12001            worker.start();
12002        }
12003    }
12004
12005    /**
12006     * Bring up the "unexpected error" dialog box for a crashing app.
12007     * Deal with edge cases (intercepts from instrumented applications,
12008     * ActivityController, error intent receivers, that sort of thing).
12009     * @param r the application crashing
12010     * @param crashInfo describing the failure
12011     */
12012    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
12013        long timeMillis = System.currentTimeMillis();
12014        String shortMsg = crashInfo.exceptionClassName;
12015        String longMsg = crashInfo.exceptionMessage;
12016        String stackTrace = crashInfo.stackTrace;
12017        if (shortMsg != null && longMsg != null) {
12018            longMsg = shortMsg + ": " + longMsg;
12019        } else if (shortMsg != null) {
12020            longMsg = shortMsg;
12021        }
12022
12023        AppErrorResult result = new AppErrorResult();
12024        synchronized (this) {
12025            if (mController != null) {
12026                try {
12027                    String name = r != null ? r.processName : null;
12028                    int pid = r != null ? r.pid : Binder.getCallingPid();
12029                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
12030                    if (!mController.appCrashed(name, pid,
12031                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
12032                        if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
12033                                && "Native crash".equals(crashInfo.exceptionClassName)) {
12034                            Slog.w(TAG, "Skip killing native crashed app " + name
12035                                    + "(" + pid + ") during testing");
12036                        } else {
12037                            Slog.w(TAG, "Force-killing crashed app " + name
12038                                    + " at watcher's request");
12039                            if (r != null) {
12040                                r.kill("crash", true);
12041                            } else {
12042                                // Huh.
12043                                Process.killProcess(pid);
12044                                Process.killProcessGroup(uid, pid);
12045                            }
12046                        }
12047                        return;
12048                    }
12049                } catch (RemoteException e) {
12050                    mController = null;
12051                    Watchdog.getInstance().setActivityController(null);
12052                }
12053            }
12054
12055            final long origId = Binder.clearCallingIdentity();
12056
12057            // If this process is running instrumentation, finish it.
12058            if (r != null && r.instrumentationClass != null) {
12059                Slog.w(TAG, "Error in app " + r.processName
12060                      + " running instrumentation " + r.instrumentationClass + ":");
12061                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
12062                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
12063                Bundle info = new Bundle();
12064                info.putString("shortMsg", shortMsg);
12065                info.putString("longMsg", longMsg);
12066                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
12067                Binder.restoreCallingIdentity(origId);
12068                return;
12069            }
12070
12071            // Log crash in battery stats.
12072            if (r != null) {
12073                mBatteryStatsService.noteProcessCrash(r.processName, r.uid);
12074            }
12075
12076            // If we can't identify the process or it's already exceeded its crash quota,
12077            // quit right away without showing a crash dialog.
12078            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
12079                Binder.restoreCallingIdentity(origId);
12080                return;
12081            }
12082
12083            Message msg = Message.obtain();
12084            msg.what = SHOW_ERROR_MSG;
12085            HashMap data = new HashMap();
12086            data.put("result", result);
12087            data.put("app", r);
12088            msg.obj = data;
12089            mHandler.sendMessage(msg);
12090
12091            Binder.restoreCallingIdentity(origId);
12092        }
12093
12094        int res = result.get();
12095
12096        Intent appErrorIntent = null;
12097        synchronized (this) {
12098            if (r != null && !r.isolated) {
12099                // XXX Can't keep track of crash time for isolated processes,
12100                // since they don't have a persistent identity.
12101                mProcessCrashTimes.put(r.info.processName, r.uid,
12102                        SystemClock.uptimeMillis());
12103            }
12104            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
12105                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
12106            }
12107        }
12108
12109        if (appErrorIntent != null) {
12110            try {
12111                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
12112            } catch (ActivityNotFoundException e) {
12113                Slog.w(TAG, "bug report receiver dissappeared", e);
12114            }
12115        }
12116    }
12117
12118    Intent createAppErrorIntentLocked(ProcessRecord r,
12119            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12120        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
12121        if (report == null) {
12122            return null;
12123        }
12124        Intent result = new Intent(Intent.ACTION_APP_ERROR);
12125        result.setComponent(r.errorReportReceiver);
12126        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
12127        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
12128        return result;
12129    }
12130
12131    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
12132            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12133        if (r.errorReportReceiver == null) {
12134            return null;
12135        }
12136
12137        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
12138            return null;
12139        }
12140
12141        ApplicationErrorReport report = new ApplicationErrorReport();
12142        report.packageName = r.info.packageName;
12143        report.installerPackageName = r.errorReportReceiver.getPackageName();
12144        report.processName = r.processName;
12145        report.time = timeMillis;
12146        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
12147
12148        if (r.crashing || r.forceCrashReport) {
12149            report.type = ApplicationErrorReport.TYPE_CRASH;
12150            report.crashInfo = crashInfo;
12151        } else if (r.notResponding) {
12152            report.type = ApplicationErrorReport.TYPE_ANR;
12153            report.anrInfo = new ApplicationErrorReport.AnrInfo();
12154
12155            report.anrInfo.activity = r.notRespondingReport.tag;
12156            report.anrInfo.cause = r.notRespondingReport.shortMsg;
12157            report.anrInfo.info = r.notRespondingReport.longMsg;
12158        }
12159
12160        return report;
12161    }
12162
12163    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
12164        enforceNotIsolatedCaller("getProcessesInErrorState");
12165        // assume our apps are happy - lazy create the list
12166        List<ActivityManager.ProcessErrorStateInfo> errList = null;
12167
12168        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12169                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12170        int userId = UserHandle.getUserId(Binder.getCallingUid());
12171
12172        synchronized (this) {
12173
12174            // iterate across all processes
12175            for (int i=mLruProcesses.size()-1; i>=0; i--) {
12176                ProcessRecord app = mLruProcesses.get(i);
12177                if (!allUsers && app.userId != userId) {
12178                    continue;
12179                }
12180                if ((app.thread != null) && (app.crashing || app.notResponding)) {
12181                    // This one's in trouble, so we'll generate a report for it
12182                    // crashes are higher priority (in case there's a crash *and* an anr)
12183                    ActivityManager.ProcessErrorStateInfo report = null;
12184                    if (app.crashing) {
12185                        report = app.crashingReport;
12186                    } else if (app.notResponding) {
12187                        report = app.notRespondingReport;
12188                    }
12189
12190                    if (report != null) {
12191                        if (errList == null) {
12192                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
12193                        }
12194                        errList.add(report);
12195                    } else {
12196                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
12197                                " crashing = " + app.crashing +
12198                                " notResponding = " + app.notResponding);
12199                    }
12200                }
12201            }
12202        }
12203
12204        return errList;
12205    }
12206
12207    static int procStateToImportance(int procState, int memAdj,
12208            ActivityManager.RunningAppProcessInfo currApp) {
12209        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
12210        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
12211            currApp.lru = memAdj;
12212        } else {
12213            currApp.lru = 0;
12214        }
12215        return imp;
12216    }
12217
12218    private void fillInProcMemInfo(ProcessRecord app,
12219            ActivityManager.RunningAppProcessInfo outInfo) {
12220        outInfo.pid = app.pid;
12221        outInfo.uid = app.info.uid;
12222        if (mHeavyWeightProcess == app) {
12223            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
12224        }
12225        if (app.persistent) {
12226            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
12227        }
12228        if (app.activities.size() > 0) {
12229            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
12230        }
12231        outInfo.lastTrimLevel = app.trimMemoryLevel;
12232        int adj = app.curAdj;
12233        int procState = app.curProcState;
12234        outInfo.importance = procStateToImportance(procState, adj, outInfo);
12235        outInfo.importanceReasonCode = app.adjTypeCode;
12236        outInfo.processState = app.curProcState;
12237    }
12238
12239    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
12240        enforceNotIsolatedCaller("getRunningAppProcesses");
12241        // Lazy instantiation of list
12242        List<ActivityManager.RunningAppProcessInfo> runList = null;
12243        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12244                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12245        int userId = UserHandle.getUserId(Binder.getCallingUid());
12246        synchronized (this) {
12247            // Iterate across all processes
12248            for (int i=mLruProcesses.size()-1; i>=0; i--) {
12249                ProcessRecord app = mLruProcesses.get(i);
12250                if (!allUsers && app.userId != userId) {
12251                    continue;
12252                }
12253                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
12254                    // Generate process state info for running application
12255                    ActivityManager.RunningAppProcessInfo currApp =
12256                        new ActivityManager.RunningAppProcessInfo(app.processName,
12257                                app.pid, app.getPackageList());
12258                    fillInProcMemInfo(app, currApp);
12259                    if (app.adjSource instanceof ProcessRecord) {
12260                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
12261                        currApp.importanceReasonImportance =
12262                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
12263                                        app.adjSourceProcState);
12264                    } else if (app.adjSource instanceof ActivityRecord) {
12265                        ActivityRecord r = (ActivityRecord)app.adjSource;
12266                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
12267                    }
12268                    if (app.adjTarget instanceof ComponentName) {
12269                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
12270                    }
12271                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
12272                    //        + " lru=" + currApp.lru);
12273                    if (runList == null) {
12274                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
12275                    }
12276                    runList.add(currApp);
12277                }
12278            }
12279        }
12280        return runList;
12281    }
12282
12283    public List<ApplicationInfo> getRunningExternalApplications() {
12284        enforceNotIsolatedCaller("getRunningExternalApplications");
12285        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
12286        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
12287        if (runningApps != null && runningApps.size() > 0) {
12288            Set<String> extList = new HashSet<String>();
12289            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
12290                if (app.pkgList != null) {
12291                    for (String pkg : app.pkgList) {
12292                        extList.add(pkg);
12293                    }
12294                }
12295            }
12296            IPackageManager pm = AppGlobals.getPackageManager();
12297            for (String pkg : extList) {
12298                try {
12299                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
12300                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
12301                        retList.add(info);
12302                    }
12303                } catch (RemoteException e) {
12304                }
12305            }
12306        }
12307        return retList;
12308    }
12309
12310    @Override
12311    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
12312        enforceNotIsolatedCaller("getMyMemoryState");
12313        synchronized (this) {
12314            ProcessRecord proc;
12315            synchronized (mPidsSelfLocked) {
12316                proc = mPidsSelfLocked.get(Binder.getCallingPid());
12317            }
12318            fillInProcMemInfo(proc, outInfo);
12319        }
12320    }
12321
12322    @Override
12323    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
12324        if (checkCallingPermission(android.Manifest.permission.DUMP)
12325                != PackageManager.PERMISSION_GRANTED) {
12326            pw.println("Permission Denial: can't dump ActivityManager from from pid="
12327                    + Binder.getCallingPid()
12328                    + ", uid=" + Binder.getCallingUid()
12329                    + " without permission "
12330                    + android.Manifest.permission.DUMP);
12331            return;
12332        }
12333
12334        boolean dumpAll = false;
12335        boolean dumpClient = false;
12336        String dumpPackage = null;
12337
12338        int opti = 0;
12339        while (opti < args.length) {
12340            String opt = args[opti];
12341            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12342                break;
12343            }
12344            opti++;
12345            if ("-a".equals(opt)) {
12346                dumpAll = true;
12347            } else if ("-c".equals(opt)) {
12348                dumpClient = true;
12349            } else if ("-p".equals(opt)) {
12350                if (opti < args.length) {
12351                    dumpPackage = args[opti];
12352                    opti++;
12353                } else {
12354                    pw.println("Error: -p option requires package argument");
12355                    return;
12356                }
12357                dumpClient = true;
12358            } else if ("-h".equals(opt)) {
12359                pw.println("Activity manager dump options:");
12360                pw.println("  [-a] [-c] [-p package] [-h] [cmd] ...");
12361                pw.println("  cmd may be one of:");
12362                pw.println("    a[ctivities]: activity stack state");
12363                pw.println("    r[recents]: recent activities state");
12364                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
12365                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
12366                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
12367                pw.println("    o[om]: out of memory management");
12368                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
12369                pw.println("    provider [COMP_SPEC]: provider client-side state");
12370                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
12371                pw.println("    as[sociations]: tracked app associations");
12372                pw.println("    service [COMP_SPEC]: service client-side state");
12373                pw.println("    package [PACKAGE_NAME]: all state related to given package");
12374                pw.println("    all: dump all activities");
12375                pw.println("    top: dump the top activity");
12376                pw.println("    write: write all pending state to storage");
12377                pw.println("    track-associations: enable association tracking");
12378                pw.println("    untrack-associations: disable and clear association tracking");
12379                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
12380                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
12381                pw.println("    a partial substring in a component name, a");
12382                pw.println("    hex object identifier.");
12383                pw.println("  -a: include all available server state.");
12384                pw.println("  -c: include client state.");
12385                pw.println("  -p: limit output to given package.");
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, dumpPackage);
12401                }
12402            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
12403                synchronized (this) {
12404                    dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
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                    dumpPackage = 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, dumpPackage);
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                    dumpPackage = 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, dumpPackage);
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                    dumpPackage = 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, dumpPackage);
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 ("associations".equals(cmd) || "as".equals(cmd)) {
12511                synchronized (this) {
12512                    dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
12513                }
12514            } else if ("services".equals(cmd) || "s".equals(cmd)) {
12515                synchronized (this) {
12516                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
12517                }
12518            } else if ("write".equals(cmd)) {
12519                mTaskPersister.flush();
12520                pw.println("All tasks persisted.");
12521                return;
12522            } else if ("track-associations".equals(cmd)) {
12523                synchronized (this) {
12524                    if (!mTrackingAssociations) {
12525                        mTrackingAssociations = true;
12526                        pw.println("Association tracking started.");
12527                    } else {
12528                        pw.println("Association tracking already enabled.");
12529                    }
12530                }
12531                return;
12532            } else if ("untrack-associations".equals(cmd)) {
12533                synchronized (this) {
12534                    if (mTrackingAssociations) {
12535                        mTrackingAssociations = false;
12536                        mAssociations.clear();
12537                        pw.println("Association tracking stopped.");
12538                    } else {
12539                        pw.println("Association tracking not running.");
12540                    }
12541                }
12542                return;
12543            } else {
12544                // Dumping a single activity?
12545                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
12546                    pw.println("Bad activity command, or no activities match: " + cmd);
12547                    pw.println("Use -h for help.");
12548                }
12549            }
12550            if (!more) {
12551                Binder.restoreCallingIdentity(origId);
12552                return;
12553            }
12554        }
12555
12556        // No piece of data specified, dump everything.
12557        synchronized (this) {
12558            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12559            pw.println();
12560            if (dumpAll) {
12561                pw.println("-------------------------------------------------------------------------------");
12562            }
12563            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12564            pw.println();
12565            if (dumpAll) {
12566                pw.println("-------------------------------------------------------------------------------");
12567            }
12568            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12569            pw.println();
12570            if (dumpAll) {
12571                pw.println("-------------------------------------------------------------------------------");
12572            }
12573            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12574            pw.println();
12575            if (dumpAll) {
12576                pw.println("-------------------------------------------------------------------------------");
12577            }
12578            dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12579            pw.println();
12580            if (dumpAll) {
12581                pw.println("-------------------------------------------------------------------------------");
12582            }
12583            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12584            if (mAssociations.size() > 0) {
12585                pw.println();
12586                if (dumpAll) {
12587                    pw.println("-------------------------------------------------------------------------------");
12588                }
12589                dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12590            }
12591            pw.println();
12592            if (dumpAll) {
12593                pw.println("-------------------------------------------------------------------------------");
12594            }
12595            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12596        }
12597        Binder.restoreCallingIdentity(origId);
12598    }
12599
12600    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12601            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
12602        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
12603
12604        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
12605                dumpPackage);
12606        boolean needSep = printedAnything;
12607
12608        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
12609                dumpPackage, needSep, "  mFocusedActivity: ");
12610        if (printed) {
12611            printedAnything = true;
12612            needSep = false;
12613        }
12614
12615        if (dumpPackage == null) {
12616            if (needSep) {
12617                pw.println();
12618            }
12619            needSep = true;
12620            printedAnything = true;
12621            mStackSupervisor.dump(pw, "  ");
12622        }
12623
12624        if (!printedAnything) {
12625            pw.println("  (nothing)");
12626        }
12627    }
12628
12629    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12630            int opti, boolean dumpAll, String dumpPackage) {
12631        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
12632
12633        boolean printedAnything = false;
12634
12635        if (mRecentTasks != null && mRecentTasks.size() > 0) {
12636            boolean printedHeader = false;
12637
12638            final int N = mRecentTasks.size();
12639            for (int i=0; i<N; i++) {
12640                TaskRecord tr = mRecentTasks.get(i);
12641                if (dumpPackage != null) {
12642                    if (tr.realActivity == null ||
12643                            !dumpPackage.equals(tr.realActivity)) {
12644                        continue;
12645                    }
12646                }
12647                if (!printedHeader) {
12648                    pw.println("  Recent tasks:");
12649                    printedHeader = true;
12650                    printedAnything = true;
12651                }
12652                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
12653                        pw.println(tr);
12654                if (dumpAll) {
12655                    mRecentTasks.get(i).dump(pw, "    ");
12656                }
12657            }
12658        }
12659
12660        if (!printedAnything) {
12661            pw.println("  (nothing)");
12662        }
12663    }
12664
12665    void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12666            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
12667        pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
12668
12669        int dumpUid = 0;
12670        if (dumpPackage != null) {
12671            IPackageManager pm = AppGlobals.getPackageManager();
12672            try {
12673                dumpUid = pm.getPackageUid(dumpPackage, 0);
12674            } catch (RemoteException e) {
12675            }
12676        }
12677
12678        boolean printedAnything = false;
12679
12680        final long now = SystemClock.uptimeMillis();
12681
12682        for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
12683            ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
12684                    = mAssociations.valueAt(i1);
12685            for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
12686                SparseArray<ArrayMap<String, Association>> sourceUids
12687                        = targetComponents.valueAt(i2);
12688                for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
12689                    ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
12690                    for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
12691                        Association ass = sourceProcesses.valueAt(i4);
12692                        if (dumpPackage != null) {
12693                            if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
12694                                    && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
12695                                continue;
12696                            }
12697                        }
12698                        printedAnything = true;
12699                        pw.print("  ");
12700                        pw.print(ass.mTargetProcess);
12701                        pw.print("/");
12702                        UserHandle.formatUid(pw, ass.mTargetUid);
12703                        pw.print(" <- ");
12704                        pw.print(ass.mSourceProcess);
12705                        pw.print("/");
12706                        UserHandle.formatUid(pw, ass.mSourceUid);
12707                        pw.println();
12708                        pw.print("    via ");
12709                        pw.print(ass.mTargetComponent.flattenToShortString());
12710                        pw.println();
12711                        pw.print("    ");
12712                        long dur = ass.mTime;
12713                        if (ass.mNesting > 0) {
12714                            dur += now - ass.mStartTime;
12715                        }
12716                        TimeUtils.formatDuration(dur, pw);
12717                        pw.print(" (");
12718                        pw.print(ass.mCount);
12719                        pw.println(" times)");
12720                        if (ass.mNesting > 0) {
12721                            pw.print("    ");
12722                            pw.print(" Currently active: ");
12723                            TimeUtils.formatDuration(now - ass.mStartTime, pw);
12724                            pw.println();
12725                        }
12726                    }
12727                }
12728            }
12729
12730        }
12731
12732        if (!printedAnything) {
12733            pw.println("  (nothing)");
12734        }
12735    }
12736
12737    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12738            int opti, boolean dumpAll, String dumpPackage) {
12739        boolean needSep = false;
12740        boolean printedAnything = false;
12741        int numPers = 0;
12742
12743        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
12744
12745        if (dumpAll) {
12746            final int NP = mProcessNames.getMap().size();
12747            for (int ip=0; ip<NP; ip++) {
12748                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
12749                final int NA = procs.size();
12750                for (int ia=0; ia<NA; ia++) {
12751                    ProcessRecord r = procs.valueAt(ia);
12752                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12753                        continue;
12754                    }
12755                    if (!needSep) {
12756                        pw.println("  All known processes:");
12757                        needSep = true;
12758                        printedAnything = true;
12759                    }
12760                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
12761                        pw.print(" UID "); pw.print(procs.keyAt(ia));
12762                        pw.print(" "); pw.println(r);
12763                    r.dump(pw, "    ");
12764                    if (r.persistent) {
12765                        numPers++;
12766                    }
12767                }
12768            }
12769        }
12770
12771        if (mIsolatedProcesses.size() > 0) {
12772            boolean printed = false;
12773            for (int i=0; i<mIsolatedProcesses.size(); i++) {
12774                ProcessRecord r = mIsolatedProcesses.valueAt(i);
12775                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12776                    continue;
12777                }
12778                if (!printed) {
12779                    if (needSep) {
12780                        pw.println();
12781                    }
12782                    pw.println("  Isolated process list (sorted by uid):");
12783                    printedAnything = true;
12784                    printed = true;
12785                    needSep = true;
12786                }
12787                pw.println(String.format("%sIsolated #%2d: %s",
12788                        "    ", i, r.toString()));
12789            }
12790        }
12791
12792        if (mLruProcesses.size() > 0) {
12793            if (needSep) {
12794                pw.println();
12795            }
12796            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
12797                    pw.print(" total, non-act at ");
12798                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12799                    pw.print(", non-svc at ");
12800                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12801                    pw.println("):");
12802            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
12803            needSep = true;
12804            printedAnything = true;
12805        }
12806
12807        if (dumpAll || dumpPackage != null) {
12808            synchronized (mPidsSelfLocked) {
12809                boolean printed = false;
12810                for (int i=0; i<mPidsSelfLocked.size(); i++) {
12811                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
12812                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12813                        continue;
12814                    }
12815                    if (!printed) {
12816                        if (needSep) pw.println();
12817                        needSep = true;
12818                        pw.println("  PID mappings:");
12819                        printed = true;
12820                        printedAnything = true;
12821                    }
12822                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
12823                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
12824                }
12825            }
12826        }
12827
12828        if (mForegroundProcesses.size() > 0) {
12829            synchronized (mPidsSelfLocked) {
12830                boolean printed = false;
12831                for (int i=0; i<mForegroundProcesses.size(); i++) {
12832                    ProcessRecord r = mPidsSelfLocked.get(
12833                            mForegroundProcesses.valueAt(i).pid);
12834                    if (dumpPackage != null && (r == null
12835                            || !r.pkgList.containsKey(dumpPackage))) {
12836                        continue;
12837                    }
12838                    if (!printed) {
12839                        if (needSep) pw.println();
12840                        needSep = true;
12841                        pw.println("  Foreground Processes:");
12842                        printed = true;
12843                        printedAnything = true;
12844                    }
12845                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
12846                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
12847                }
12848            }
12849        }
12850
12851        if (mPersistentStartingProcesses.size() > 0) {
12852            if (needSep) pw.println();
12853            needSep = true;
12854            printedAnything = true;
12855            pw.println("  Persisent processes that are starting:");
12856            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
12857                    "Starting Norm", "Restarting PERS", dumpPackage);
12858        }
12859
12860        if (mRemovedProcesses.size() > 0) {
12861            if (needSep) pw.println();
12862            needSep = true;
12863            printedAnything = true;
12864            pw.println("  Processes that are being removed:");
12865            dumpProcessList(pw, this, mRemovedProcesses, "    ",
12866                    "Removed Norm", "Removed PERS", dumpPackage);
12867        }
12868
12869        if (mProcessesOnHold.size() > 0) {
12870            if (needSep) pw.println();
12871            needSep = true;
12872            printedAnything = true;
12873            pw.println("  Processes that are on old until the system is ready:");
12874            dumpProcessList(pw, this, mProcessesOnHold, "    ",
12875                    "OnHold Norm", "OnHold PERS", dumpPackage);
12876        }
12877
12878        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
12879
12880        if (mProcessCrashTimes.getMap().size() > 0) {
12881            boolean printed = false;
12882            long now = SystemClock.uptimeMillis();
12883            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
12884            final int NP = pmap.size();
12885            for (int ip=0; ip<NP; ip++) {
12886                String pname = pmap.keyAt(ip);
12887                SparseArray<Long> uids = pmap.valueAt(ip);
12888                final int N = uids.size();
12889                for (int i=0; i<N; i++) {
12890                    int puid = uids.keyAt(i);
12891                    ProcessRecord r = mProcessNames.get(pname, puid);
12892                    if (dumpPackage != null && (r == null
12893                            || !r.pkgList.containsKey(dumpPackage))) {
12894                        continue;
12895                    }
12896                    if (!printed) {
12897                        if (needSep) pw.println();
12898                        needSep = true;
12899                        pw.println("  Time since processes crashed:");
12900                        printed = true;
12901                        printedAnything = true;
12902                    }
12903                    pw.print("    Process "); pw.print(pname);
12904                            pw.print(" uid "); pw.print(puid);
12905                            pw.print(": last crashed ");
12906                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
12907                            pw.println(" ago");
12908                }
12909            }
12910        }
12911
12912        if (mBadProcesses.getMap().size() > 0) {
12913            boolean printed = false;
12914            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
12915            final int NP = pmap.size();
12916            for (int ip=0; ip<NP; ip++) {
12917                String pname = pmap.keyAt(ip);
12918                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
12919                final int N = uids.size();
12920                for (int i=0; i<N; i++) {
12921                    int puid = uids.keyAt(i);
12922                    ProcessRecord r = mProcessNames.get(pname, puid);
12923                    if (dumpPackage != null && (r == null
12924                            || !r.pkgList.containsKey(dumpPackage))) {
12925                        continue;
12926                    }
12927                    if (!printed) {
12928                        if (needSep) pw.println();
12929                        needSep = true;
12930                        pw.println("  Bad processes:");
12931                        printedAnything = true;
12932                    }
12933                    BadProcessInfo info = uids.valueAt(i);
12934                    pw.print("    Bad process "); pw.print(pname);
12935                            pw.print(" uid "); pw.print(puid);
12936                            pw.print(": crashed at time "); pw.println(info.time);
12937                    if (info.shortMsg != null) {
12938                        pw.print("      Short msg: "); pw.println(info.shortMsg);
12939                    }
12940                    if (info.longMsg != null) {
12941                        pw.print("      Long msg: "); pw.println(info.longMsg);
12942                    }
12943                    if (info.stack != null) {
12944                        pw.println("      Stack:");
12945                        int lastPos = 0;
12946                        for (int pos=0; pos<info.stack.length(); pos++) {
12947                            if (info.stack.charAt(pos) == '\n') {
12948                                pw.print("        ");
12949                                pw.write(info.stack, lastPos, pos-lastPos);
12950                                pw.println();
12951                                lastPos = pos+1;
12952                            }
12953                        }
12954                        if (lastPos < info.stack.length()) {
12955                            pw.print("        ");
12956                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
12957                            pw.println();
12958                        }
12959                    }
12960                }
12961            }
12962        }
12963
12964        if (dumpPackage == null) {
12965            pw.println();
12966            needSep = false;
12967            pw.println("  mStartedUsers:");
12968            for (int i=0; i<mStartedUsers.size(); i++) {
12969                UserStartedState uss = mStartedUsers.valueAt(i);
12970                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
12971                        pw.print(": "); uss.dump("", pw);
12972            }
12973            pw.print("  mStartedUserArray: [");
12974            for (int i=0; i<mStartedUserArray.length; i++) {
12975                if (i > 0) pw.print(", ");
12976                pw.print(mStartedUserArray[i]);
12977            }
12978            pw.println("]");
12979            pw.print("  mUserLru: [");
12980            for (int i=0; i<mUserLru.size(); i++) {
12981                if (i > 0) pw.print(", ");
12982                pw.print(mUserLru.get(i));
12983            }
12984            pw.println("]");
12985            if (dumpAll) {
12986                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
12987            }
12988            synchronized (mUserProfileGroupIdsSelfLocked) {
12989                if (mUserProfileGroupIdsSelfLocked.size() > 0) {
12990                    pw.println("  mUserProfileGroupIds:");
12991                    for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
12992                        pw.print("    User #");
12993                        pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
12994                        pw.print(" -> profile #");
12995                        pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
12996                    }
12997                }
12998            }
12999        }
13000        if (mHomeProcess != null && (dumpPackage == null
13001                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
13002            if (needSep) {
13003                pw.println();
13004                needSep = false;
13005            }
13006            pw.println("  mHomeProcess: " + mHomeProcess);
13007        }
13008        if (mPreviousProcess != null && (dumpPackage == null
13009                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
13010            if (needSep) {
13011                pw.println();
13012                needSep = false;
13013            }
13014            pw.println("  mPreviousProcess: " + mPreviousProcess);
13015        }
13016        if (dumpAll) {
13017            StringBuilder sb = new StringBuilder(128);
13018            sb.append("  mPreviousProcessVisibleTime: ");
13019            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
13020            pw.println(sb);
13021        }
13022        if (mHeavyWeightProcess != null && (dumpPackage == null
13023                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
13024            if (needSep) {
13025                pw.println();
13026                needSep = false;
13027            }
13028            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
13029        }
13030        if (dumpPackage == null) {
13031            pw.println("  mConfiguration: " + mConfiguration);
13032        }
13033        if (dumpAll) {
13034            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
13035            if (mCompatModePackages.getPackages().size() > 0) {
13036                boolean printed = false;
13037                for (Map.Entry<String, Integer> entry
13038                        : mCompatModePackages.getPackages().entrySet()) {
13039                    String pkg = entry.getKey();
13040                    int mode = entry.getValue();
13041                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
13042                        continue;
13043                    }
13044                    if (!printed) {
13045                        pw.println("  mScreenCompatPackages:");
13046                        printed = true;
13047                    }
13048                    pw.print("    "); pw.print(pkg); pw.print(": ");
13049                            pw.print(mode); pw.println();
13050                }
13051            }
13052        }
13053        if (dumpPackage == null) {
13054            pw.println("  mWakefulness="
13055                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
13056            pw.println("  mSleeping=" + mSleeping + " mLockScreenShown="
13057                    + lockScreenShownToString());
13058            pw.println("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice
13059                    + " mTestPssMode=" + mTestPssMode);
13060        }
13061        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
13062                || mOrigWaitForDebugger) {
13063            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
13064                    || dumpPackage.equals(mOrigDebugApp)) {
13065                if (needSep) {
13066                    pw.println();
13067                    needSep = false;
13068                }
13069                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
13070                        + " mDebugTransient=" + mDebugTransient
13071                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
13072            }
13073        }
13074        if (mOpenGlTraceApp != null) {
13075            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
13076                if (needSep) {
13077                    pw.println();
13078                    needSep = false;
13079                }
13080                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
13081            }
13082        }
13083        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
13084                || mProfileFd != null) {
13085            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
13086                if (needSep) {
13087                    pw.println();
13088                    needSep = false;
13089                }
13090                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
13091                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
13092                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
13093                        + mAutoStopProfiler);
13094                pw.println("  mProfileType=" + mProfileType);
13095            }
13096        }
13097        if (dumpPackage == null) {
13098            if (mAlwaysFinishActivities || mController != null) {
13099                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
13100                        + " mController=" + mController);
13101            }
13102            if (dumpAll) {
13103                pw.println("  Total persistent processes: " + numPers);
13104                pw.println("  mProcessesReady=" + mProcessesReady
13105                        + " mSystemReady=" + mSystemReady
13106                        + " mBooted=" + mBooted
13107                        + " mFactoryTest=" + mFactoryTest);
13108                pw.println("  mBooting=" + mBooting
13109                        + " mCallFinishBooting=" + mCallFinishBooting
13110                        + " mBootAnimationComplete=" + mBootAnimationComplete);
13111                pw.print("  mLastPowerCheckRealtime=");
13112                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
13113                        pw.println("");
13114                pw.print("  mLastPowerCheckUptime=");
13115                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
13116                        pw.println("");
13117                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
13118                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
13119                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
13120                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
13121                        + " (" + mLruProcesses.size() + " total)"
13122                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
13123                        + " mNumServiceProcs=" + mNumServiceProcs
13124                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
13125                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
13126                        + " mLastMemoryLevel" + mLastMemoryLevel
13127                        + " mLastNumProcesses" + mLastNumProcesses);
13128                long now = SystemClock.uptimeMillis();
13129                pw.print("  mLastIdleTime=");
13130                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
13131                        pw.print(" mLowRamSinceLastIdle=");
13132                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
13133                        pw.println();
13134            }
13135        }
13136
13137        if (!printedAnything) {
13138            pw.println("  (nothing)");
13139        }
13140    }
13141
13142    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
13143            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
13144        if (mProcessesToGc.size() > 0) {
13145            boolean printed = false;
13146            long now = SystemClock.uptimeMillis();
13147            for (int i=0; i<mProcessesToGc.size(); i++) {
13148                ProcessRecord proc = mProcessesToGc.get(i);
13149                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
13150                    continue;
13151                }
13152                if (!printed) {
13153                    if (needSep) pw.println();
13154                    needSep = true;
13155                    pw.println("  Processes that are waiting to GC:");
13156                    printed = true;
13157                }
13158                pw.print("    Process "); pw.println(proc);
13159                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
13160                        pw.print(", last gced=");
13161                        pw.print(now-proc.lastRequestedGc);
13162                        pw.print(" ms ago, last lowMem=");
13163                        pw.print(now-proc.lastLowMemory);
13164                        pw.println(" ms ago");
13165
13166            }
13167        }
13168        return needSep;
13169    }
13170
13171    void printOomLevel(PrintWriter pw, String name, int adj) {
13172        pw.print("    ");
13173        if (adj >= 0) {
13174            pw.print(' ');
13175            if (adj < 10) pw.print(' ');
13176        } else {
13177            if (adj > -10) pw.print(' ');
13178        }
13179        pw.print(adj);
13180        pw.print(": ");
13181        pw.print(name);
13182        pw.print(" (");
13183        pw.print(mProcessList.getMemLevel(adj)/1024);
13184        pw.println(" kB)");
13185    }
13186
13187    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13188            int opti, boolean dumpAll) {
13189        boolean needSep = false;
13190
13191        if (mLruProcesses.size() > 0) {
13192            if (needSep) pw.println();
13193            needSep = true;
13194            pw.println("  OOM levels:");
13195            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
13196            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
13197            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
13198            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
13199            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
13200            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
13201            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
13202            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
13203            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
13204            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
13205            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
13206            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
13207            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
13208            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
13209
13210            if (needSep) pw.println();
13211            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
13212                    pw.print(" total, non-act at ");
13213                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
13214                    pw.print(", non-svc at ");
13215                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
13216                    pw.println("):");
13217            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
13218            needSep = true;
13219        }
13220
13221        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
13222
13223        pw.println();
13224        pw.println("  mHomeProcess: " + mHomeProcess);
13225        pw.println("  mPreviousProcess: " + mPreviousProcess);
13226        if (mHeavyWeightProcess != null) {
13227            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
13228        }
13229
13230        return true;
13231    }
13232
13233    /**
13234     * There are three ways to call this:
13235     *  - no provider specified: dump all the providers
13236     *  - a flattened component name that matched an existing provider was specified as the
13237     *    first arg: dump that one provider
13238     *  - the first arg isn't the flattened component name of an existing provider:
13239     *    dump all providers whose component contains the first arg as a substring
13240     */
13241    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13242            int opti, boolean dumpAll) {
13243        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
13244    }
13245
13246    static class ItemMatcher {
13247        ArrayList<ComponentName> components;
13248        ArrayList<String> strings;
13249        ArrayList<Integer> objects;
13250        boolean all;
13251
13252        ItemMatcher() {
13253            all = true;
13254        }
13255
13256        void build(String name) {
13257            ComponentName componentName = ComponentName.unflattenFromString(name);
13258            if (componentName != null) {
13259                if (components == null) {
13260                    components = new ArrayList<ComponentName>();
13261                }
13262                components.add(componentName);
13263                all = false;
13264            } else {
13265                int objectId = 0;
13266                // Not a '/' separated full component name; maybe an object ID?
13267                try {
13268                    objectId = Integer.parseInt(name, 16);
13269                    if (objects == null) {
13270                        objects = new ArrayList<Integer>();
13271                    }
13272                    objects.add(objectId);
13273                    all = false;
13274                } catch (RuntimeException e) {
13275                    // Not an integer; just do string match.
13276                    if (strings == null) {
13277                        strings = new ArrayList<String>();
13278                    }
13279                    strings.add(name);
13280                    all = false;
13281                }
13282            }
13283        }
13284
13285        int build(String[] args, int opti) {
13286            for (; opti<args.length; opti++) {
13287                String name = args[opti];
13288                if ("--".equals(name)) {
13289                    return opti+1;
13290                }
13291                build(name);
13292            }
13293            return opti;
13294        }
13295
13296        boolean match(Object object, ComponentName comp) {
13297            if (all) {
13298                return true;
13299            }
13300            if (components != null) {
13301                for (int i=0; i<components.size(); i++) {
13302                    if (components.get(i).equals(comp)) {
13303                        return true;
13304                    }
13305                }
13306            }
13307            if (objects != null) {
13308                for (int i=0; i<objects.size(); i++) {
13309                    if (System.identityHashCode(object) == objects.get(i)) {
13310                        return true;
13311                    }
13312                }
13313            }
13314            if (strings != null) {
13315                String flat = comp.flattenToString();
13316                for (int i=0; i<strings.size(); i++) {
13317                    if (flat.contains(strings.get(i))) {
13318                        return true;
13319                    }
13320                }
13321            }
13322            return false;
13323        }
13324    }
13325
13326    /**
13327     * There are three things that cmd can be:
13328     *  - a flattened component name that matches an existing activity
13329     *  - the cmd arg isn't the flattened component name of an existing activity:
13330     *    dump all activity whose component contains the cmd as a substring
13331     *  - A hex number of the ActivityRecord object instance.
13332     */
13333    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13334            int opti, boolean dumpAll) {
13335        ArrayList<ActivityRecord> activities;
13336
13337        synchronized (this) {
13338            activities = mStackSupervisor.getDumpActivitiesLocked(name);
13339        }
13340
13341        if (activities.size() <= 0) {
13342            return false;
13343        }
13344
13345        String[] newArgs = new String[args.length - opti];
13346        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13347
13348        TaskRecord lastTask = null;
13349        boolean needSep = false;
13350        for (int i=activities.size()-1; i>=0; i--) {
13351            ActivityRecord r = activities.get(i);
13352            if (needSep) {
13353                pw.println();
13354            }
13355            needSep = true;
13356            synchronized (this) {
13357                if (lastTask != r.task) {
13358                    lastTask = r.task;
13359                    pw.print("TASK "); pw.print(lastTask.affinity);
13360                            pw.print(" id="); pw.println(lastTask.taskId);
13361                    if (dumpAll) {
13362                        lastTask.dump(pw, "  ");
13363                    }
13364                }
13365            }
13366            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
13367        }
13368        return true;
13369    }
13370
13371    /**
13372     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
13373     * there is a thread associated with the activity.
13374     */
13375    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
13376            final ActivityRecord r, String[] args, boolean dumpAll) {
13377        String innerPrefix = prefix + "  ";
13378        synchronized (this) {
13379            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
13380                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
13381                    pw.print(" pid=");
13382                    if (r.app != null) pw.println(r.app.pid);
13383                    else pw.println("(not running)");
13384            if (dumpAll) {
13385                r.dump(pw, innerPrefix);
13386            }
13387        }
13388        if (r.app != null && r.app.thread != null) {
13389            // flush anything that is already in the PrintWriter since the thread is going
13390            // to write to the file descriptor directly
13391            pw.flush();
13392            try {
13393                TransferPipe tp = new TransferPipe();
13394                try {
13395                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
13396                            r.appToken, innerPrefix, args);
13397                    tp.go(fd);
13398                } finally {
13399                    tp.kill();
13400                }
13401            } catch (IOException e) {
13402                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
13403            } catch (RemoteException e) {
13404                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
13405            }
13406        }
13407    }
13408
13409    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13410            int opti, boolean dumpAll, String dumpPackage) {
13411        boolean needSep = false;
13412        boolean onlyHistory = false;
13413        boolean printedAnything = false;
13414
13415        if ("history".equals(dumpPackage)) {
13416            if (opti < args.length && "-s".equals(args[opti])) {
13417                dumpAll = false;
13418            }
13419            onlyHistory = true;
13420            dumpPackage = null;
13421        }
13422
13423        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
13424        if (!onlyHistory && dumpAll) {
13425            if (mRegisteredReceivers.size() > 0) {
13426                boolean printed = false;
13427                Iterator it = mRegisteredReceivers.values().iterator();
13428                while (it.hasNext()) {
13429                    ReceiverList r = (ReceiverList)it.next();
13430                    if (dumpPackage != null && (r.app == null ||
13431                            !dumpPackage.equals(r.app.info.packageName))) {
13432                        continue;
13433                    }
13434                    if (!printed) {
13435                        pw.println("  Registered Receivers:");
13436                        needSep = true;
13437                        printed = true;
13438                        printedAnything = true;
13439                    }
13440                    pw.print("  * "); pw.println(r);
13441                    r.dump(pw, "    ");
13442                }
13443            }
13444
13445            if (mReceiverResolver.dump(pw, needSep ?
13446                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
13447                    "    ", dumpPackage, false, false)) {
13448                needSep = true;
13449                printedAnything = true;
13450            }
13451        }
13452
13453        for (BroadcastQueue q : mBroadcastQueues) {
13454            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
13455            printedAnything |= needSep;
13456        }
13457
13458        needSep = true;
13459
13460        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
13461            for (int user=0; user<mStickyBroadcasts.size(); user++) {
13462                if (needSep) {
13463                    pw.println();
13464                }
13465                needSep = true;
13466                printedAnything = true;
13467                pw.print("  Sticky broadcasts for user ");
13468                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
13469                StringBuilder sb = new StringBuilder(128);
13470                for (Map.Entry<String, ArrayList<Intent>> ent
13471                        : mStickyBroadcasts.valueAt(user).entrySet()) {
13472                    pw.print("  * Sticky action "); pw.print(ent.getKey());
13473                    if (dumpAll) {
13474                        pw.println(":");
13475                        ArrayList<Intent> intents = ent.getValue();
13476                        final int N = intents.size();
13477                        for (int i=0; i<N; i++) {
13478                            sb.setLength(0);
13479                            sb.append("    Intent: ");
13480                            intents.get(i).toShortString(sb, false, true, false, false);
13481                            pw.println(sb.toString());
13482                            Bundle bundle = intents.get(i).getExtras();
13483                            if (bundle != null) {
13484                                pw.print("      ");
13485                                pw.println(bundle.toString());
13486                            }
13487                        }
13488                    } else {
13489                        pw.println("");
13490                    }
13491                }
13492            }
13493        }
13494
13495        if (!onlyHistory && dumpAll) {
13496            pw.println();
13497            for (BroadcastQueue queue : mBroadcastQueues) {
13498                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
13499                        + queue.mBroadcastsScheduled);
13500            }
13501            pw.println("  mHandler:");
13502            mHandler.dump(new PrintWriterPrinter(pw), "    ");
13503            needSep = true;
13504            printedAnything = true;
13505        }
13506
13507        if (!printedAnything) {
13508            pw.println("  (nothing)");
13509        }
13510    }
13511
13512    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13513            int opti, boolean dumpAll, String dumpPackage) {
13514        boolean needSep;
13515        boolean printedAnything = false;
13516
13517        ItemMatcher matcher = new ItemMatcher();
13518        matcher.build(args, opti);
13519
13520        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
13521
13522        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
13523        printedAnything |= needSep;
13524
13525        if (mLaunchingProviders.size() > 0) {
13526            boolean printed = false;
13527            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
13528                ContentProviderRecord r = mLaunchingProviders.get(i);
13529                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
13530                    continue;
13531                }
13532                if (!printed) {
13533                    if (needSep) pw.println();
13534                    needSep = true;
13535                    pw.println("  Launching content providers:");
13536                    printed = true;
13537                    printedAnything = true;
13538                }
13539                pw.print("  Launching #"); pw.print(i); pw.print(": ");
13540                        pw.println(r);
13541            }
13542        }
13543
13544        if (mGrantedUriPermissions.size() > 0) {
13545            boolean printed = false;
13546            int dumpUid = -2;
13547            if (dumpPackage != null) {
13548                try {
13549                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
13550                } catch (NameNotFoundException e) {
13551                    dumpUid = -1;
13552                }
13553            }
13554            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
13555                int uid = mGrantedUriPermissions.keyAt(i);
13556                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
13557                    continue;
13558                }
13559                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
13560                if (!printed) {
13561                    if (needSep) pw.println();
13562                    needSep = true;
13563                    pw.println("  Granted Uri Permissions:");
13564                    printed = true;
13565                    printedAnything = true;
13566                }
13567                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
13568                for (UriPermission perm : perms.values()) {
13569                    pw.print("    "); pw.println(perm);
13570                    if (dumpAll) {
13571                        perm.dump(pw, "      ");
13572                    }
13573                }
13574            }
13575        }
13576
13577        if (!printedAnything) {
13578            pw.println("  (nothing)");
13579        }
13580    }
13581
13582    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13583            int opti, boolean dumpAll, String dumpPackage) {
13584        boolean printed = false;
13585
13586        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
13587
13588        if (mIntentSenderRecords.size() > 0) {
13589            Iterator<WeakReference<PendingIntentRecord>> it
13590                    = mIntentSenderRecords.values().iterator();
13591            while (it.hasNext()) {
13592                WeakReference<PendingIntentRecord> ref = it.next();
13593                PendingIntentRecord rec = ref != null ? ref.get(): null;
13594                if (dumpPackage != null && (rec == null
13595                        || !dumpPackage.equals(rec.key.packageName))) {
13596                    continue;
13597                }
13598                printed = true;
13599                if (rec != null) {
13600                    pw.print("  * "); pw.println(rec);
13601                    if (dumpAll) {
13602                        rec.dump(pw, "    ");
13603                    }
13604                } else {
13605                    pw.print("  * "); pw.println(ref);
13606                }
13607            }
13608        }
13609
13610        if (!printed) {
13611            pw.println("  (nothing)");
13612        }
13613    }
13614
13615    private static final int dumpProcessList(PrintWriter pw,
13616            ActivityManagerService service, List list,
13617            String prefix, String normalLabel, String persistentLabel,
13618            String dumpPackage) {
13619        int numPers = 0;
13620        final int N = list.size()-1;
13621        for (int i=N; i>=0; i--) {
13622            ProcessRecord r = (ProcessRecord)list.get(i);
13623            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
13624                continue;
13625            }
13626            pw.println(String.format("%s%s #%2d: %s",
13627                    prefix, (r.persistent ? persistentLabel : normalLabel),
13628                    i, r.toString()));
13629            if (r.persistent) {
13630                numPers++;
13631            }
13632        }
13633        return numPers;
13634    }
13635
13636    private static final boolean dumpProcessOomList(PrintWriter pw,
13637            ActivityManagerService service, List<ProcessRecord> origList,
13638            String prefix, String normalLabel, String persistentLabel,
13639            boolean inclDetails, String dumpPackage) {
13640
13641        ArrayList<Pair<ProcessRecord, Integer>> list
13642                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
13643        for (int i=0; i<origList.size(); i++) {
13644            ProcessRecord r = origList.get(i);
13645            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13646                continue;
13647            }
13648            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
13649        }
13650
13651        if (list.size() <= 0) {
13652            return false;
13653        }
13654
13655        Comparator<Pair<ProcessRecord, Integer>> comparator
13656                = new Comparator<Pair<ProcessRecord, Integer>>() {
13657            @Override
13658            public int compare(Pair<ProcessRecord, Integer> object1,
13659                    Pair<ProcessRecord, Integer> object2) {
13660                if (object1.first.setAdj != object2.first.setAdj) {
13661                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
13662                }
13663                if (object1.second.intValue() != object2.second.intValue()) {
13664                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
13665                }
13666                return 0;
13667            }
13668        };
13669
13670        Collections.sort(list, comparator);
13671
13672        final long curRealtime = SystemClock.elapsedRealtime();
13673        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
13674        final long curUptime = SystemClock.uptimeMillis();
13675        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
13676
13677        for (int i=list.size()-1; i>=0; i--) {
13678            ProcessRecord r = list.get(i).first;
13679            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
13680            char schedGroup;
13681            switch (r.setSchedGroup) {
13682                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
13683                    schedGroup = 'B';
13684                    break;
13685                case Process.THREAD_GROUP_DEFAULT:
13686                    schedGroup = 'F';
13687                    break;
13688                default:
13689                    schedGroup = '?';
13690                    break;
13691            }
13692            char foreground;
13693            if (r.foregroundActivities) {
13694                foreground = 'A';
13695            } else if (r.foregroundServices) {
13696                foreground = 'S';
13697            } else {
13698                foreground = ' ';
13699            }
13700            String procState = ProcessList.makeProcStateString(r.curProcState);
13701            pw.print(prefix);
13702            pw.print(r.persistent ? persistentLabel : normalLabel);
13703            pw.print(" #");
13704            int num = (origList.size()-1)-list.get(i).second;
13705            if (num < 10) pw.print(' ');
13706            pw.print(num);
13707            pw.print(": ");
13708            pw.print(oomAdj);
13709            pw.print(' ');
13710            pw.print(schedGroup);
13711            pw.print('/');
13712            pw.print(foreground);
13713            pw.print('/');
13714            pw.print(procState);
13715            pw.print(" trm:");
13716            if (r.trimMemoryLevel < 10) pw.print(' ');
13717            pw.print(r.trimMemoryLevel);
13718            pw.print(' ');
13719            pw.print(r.toShortString());
13720            pw.print(" (");
13721            pw.print(r.adjType);
13722            pw.println(')');
13723            if (r.adjSource != null || r.adjTarget != null) {
13724                pw.print(prefix);
13725                pw.print("    ");
13726                if (r.adjTarget instanceof ComponentName) {
13727                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
13728                } else if (r.adjTarget != null) {
13729                    pw.print(r.adjTarget.toString());
13730                } else {
13731                    pw.print("{null}");
13732                }
13733                pw.print("<=");
13734                if (r.adjSource instanceof ProcessRecord) {
13735                    pw.print("Proc{");
13736                    pw.print(((ProcessRecord)r.adjSource).toShortString());
13737                    pw.println("}");
13738                } else if (r.adjSource != null) {
13739                    pw.println(r.adjSource.toString());
13740                } else {
13741                    pw.println("{null}");
13742                }
13743            }
13744            if (inclDetails) {
13745                pw.print(prefix);
13746                pw.print("    ");
13747                pw.print("oom: max="); pw.print(r.maxAdj);
13748                pw.print(" curRaw="); pw.print(r.curRawAdj);
13749                pw.print(" setRaw="); pw.print(r.setRawAdj);
13750                pw.print(" cur="); pw.print(r.curAdj);
13751                pw.print(" set="); pw.println(r.setAdj);
13752                pw.print(prefix);
13753                pw.print("    ");
13754                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
13755                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
13756                pw.print(" lastPss="); pw.print(r.lastPss);
13757                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
13758                pw.print(prefix);
13759                pw.print("    ");
13760                pw.print("cached="); pw.print(r.cached);
13761                pw.print(" empty="); pw.print(r.empty);
13762                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
13763
13764                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
13765                    if (r.lastWakeTime != 0) {
13766                        long wtime;
13767                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
13768                        synchronized (stats) {
13769                            wtime = stats.getProcessWakeTime(r.info.uid,
13770                                    r.pid, curRealtime);
13771                        }
13772                        long timeUsed = wtime - r.lastWakeTime;
13773                        pw.print(prefix);
13774                        pw.print("    ");
13775                        pw.print("keep awake over ");
13776                        TimeUtils.formatDuration(realtimeSince, pw);
13777                        pw.print(" used ");
13778                        TimeUtils.formatDuration(timeUsed, pw);
13779                        pw.print(" (");
13780                        pw.print((timeUsed*100)/realtimeSince);
13781                        pw.println("%)");
13782                    }
13783                    if (r.lastCpuTime != 0) {
13784                        long timeUsed = r.curCpuTime - r.lastCpuTime;
13785                        pw.print(prefix);
13786                        pw.print("    ");
13787                        pw.print("run cpu over ");
13788                        TimeUtils.formatDuration(uptimeSince, pw);
13789                        pw.print(" used ");
13790                        TimeUtils.formatDuration(timeUsed, pw);
13791                        pw.print(" (");
13792                        pw.print((timeUsed*100)/uptimeSince);
13793                        pw.println("%)");
13794                    }
13795                }
13796            }
13797        }
13798        return true;
13799    }
13800
13801    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
13802            String[] args) {
13803        ArrayList<ProcessRecord> procs;
13804        synchronized (this) {
13805            if (args != null && args.length > start
13806                    && args[start].charAt(0) != '-') {
13807                procs = new ArrayList<ProcessRecord>();
13808                int pid = -1;
13809                try {
13810                    pid = Integer.parseInt(args[start]);
13811                } catch (NumberFormatException e) {
13812                }
13813                for (int i=mLruProcesses.size()-1; i>=0; i--) {
13814                    ProcessRecord proc = mLruProcesses.get(i);
13815                    if (proc.pid == pid) {
13816                        procs.add(proc);
13817                    } else if (allPkgs && proc.pkgList != null
13818                            && proc.pkgList.containsKey(args[start])) {
13819                        procs.add(proc);
13820                    } else if (proc.processName.equals(args[start])) {
13821                        procs.add(proc);
13822                    }
13823                }
13824                if (procs.size() <= 0) {
13825                    return null;
13826                }
13827            } else {
13828                procs = new ArrayList<ProcessRecord>(mLruProcesses);
13829            }
13830        }
13831        return procs;
13832    }
13833
13834    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
13835            PrintWriter pw, String[] args) {
13836        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
13837        if (procs == null) {
13838            pw.println("No process found for: " + args[0]);
13839            return;
13840        }
13841
13842        long uptime = SystemClock.uptimeMillis();
13843        long realtime = SystemClock.elapsedRealtime();
13844        pw.println("Applications Graphics Acceleration Info:");
13845        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13846
13847        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13848            ProcessRecord r = procs.get(i);
13849            if (r.thread != null) {
13850                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
13851                pw.flush();
13852                try {
13853                    TransferPipe tp = new TransferPipe();
13854                    try {
13855                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
13856                        tp.go(fd);
13857                    } finally {
13858                        tp.kill();
13859                    }
13860                } catch (IOException e) {
13861                    pw.println("Failure while dumping the app: " + r);
13862                    pw.flush();
13863                } catch (RemoteException e) {
13864                    pw.println("Got a RemoteException while dumping the app " + r);
13865                    pw.flush();
13866                }
13867            }
13868        }
13869    }
13870
13871    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
13872        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
13873        if (procs == null) {
13874            pw.println("No process found for: " + args[0]);
13875            return;
13876        }
13877
13878        pw.println("Applications Database Info:");
13879
13880        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13881            ProcessRecord r = procs.get(i);
13882            if (r.thread != null) {
13883                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
13884                pw.flush();
13885                try {
13886                    TransferPipe tp = new TransferPipe();
13887                    try {
13888                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
13889                        tp.go(fd);
13890                    } finally {
13891                        tp.kill();
13892                    }
13893                } catch (IOException e) {
13894                    pw.println("Failure while dumping the app: " + r);
13895                    pw.flush();
13896                } catch (RemoteException e) {
13897                    pw.println("Got a RemoteException while dumping the app " + r);
13898                    pw.flush();
13899                }
13900            }
13901        }
13902    }
13903
13904    final static class MemItem {
13905        final boolean isProc;
13906        final String label;
13907        final String shortLabel;
13908        final long pss;
13909        final int id;
13910        final boolean hasActivities;
13911        ArrayList<MemItem> subitems;
13912
13913        public MemItem(String _label, String _shortLabel, long _pss, int _id,
13914                boolean _hasActivities) {
13915            isProc = true;
13916            label = _label;
13917            shortLabel = _shortLabel;
13918            pss = _pss;
13919            id = _id;
13920            hasActivities = _hasActivities;
13921        }
13922
13923        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
13924            isProc = false;
13925            label = _label;
13926            shortLabel = _shortLabel;
13927            pss = _pss;
13928            id = _id;
13929            hasActivities = false;
13930        }
13931    }
13932
13933    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
13934            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
13935        if (sort && !isCompact) {
13936            Collections.sort(items, new Comparator<MemItem>() {
13937                @Override
13938                public int compare(MemItem lhs, MemItem rhs) {
13939                    if (lhs.pss < rhs.pss) {
13940                        return 1;
13941                    } else if (lhs.pss > rhs.pss) {
13942                        return -1;
13943                    }
13944                    return 0;
13945                }
13946            });
13947        }
13948
13949        for (int i=0; i<items.size(); i++) {
13950            MemItem mi = items.get(i);
13951            if (!isCompact) {
13952                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
13953            } else if (mi.isProc) {
13954                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
13955                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
13956                pw.println(mi.hasActivities ? ",a" : ",e");
13957            } else {
13958                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
13959                pw.println(mi.pss);
13960            }
13961            if (mi.subitems != null) {
13962                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
13963                        true, isCompact);
13964            }
13965        }
13966    }
13967
13968    // These are in KB.
13969    static final long[] DUMP_MEM_BUCKETS = new long[] {
13970        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
13971        120*1024, 160*1024, 200*1024,
13972        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
13973        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
13974    };
13975
13976    static final void appendMemBucket(StringBuilder out, long memKB, String label,
13977            boolean stackLike) {
13978        int start = label.lastIndexOf('.');
13979        if (start >= 0) start++;
13980        else start = 0;
13981        int end = label.length();
13982        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
13983            if (DUMP_MEM_BUCKETS[i] >= memKB) {
13984                long bucket = DUMP_MEM_BUCKETS[i]/1024;
13985                out.append(bucket);
13986                out.append(stackLike ? "MB." : "MB ");
13987                out.append(label, start, end);
13988                return;
13989            }
13990        }
13991        out.append(memKB/1024);
13992        out.append(stackLike ? "MB." : "MB ");
13993        out.append(label, start, end);
13994    }
13995
13996    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
13997            ProcessList.NATIVE_ADJ,
13998            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
13999            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
14000            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
14001            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
14002            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
14003            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
14004    };
14005    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
14006            "Native",
14007            "System", "Persistent", "Persistent Service", "Foreground",
14008            "Visible", "Perceptible",
14009            "Heavy Weight", "Backup",
14010            "A Services", "Home",
14011            "Previous", "B Services", "Cached"
14012    };
14013    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
14014            "native",
14015            "sys", "pers", "persvc", "fore",
14016            "vis", "percept",
14017            "heavy", "backup",
14018            "servicea", "home",
14019            "prev", "serviceb", "cached"
14020    };
14021
14022    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
14023            long realtime, boolean isCheckinRequest, boolean isCompact) {
14024        if (isCheckinRequest || isCompact) {
14025            // short checkin version
14026            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
14027        } else {
14028            pw.println("Applications Memory Usage (kB):");
14029            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
14030        }
14031    }
14032
14033    private static final int KSM_SHARED = 0;
14034    private static final int KSM_SHARING = 1;
14035    private static final int KSM_UNSHARED = 2;
14036    private static final int KSM_VOLATILE = 3;
14037
14038    private final long[] getKsmInfo() {
14039        long[] longOut = new long[4];
14040        final int[] SINGLE_LONG_FORMAT = new int[] {
14041            Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
14042        };
14043        long[] longTmp = new long[1];
14044        Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
14045                SINGLE_LONG_FORMAT, null, longTmp, null);
14046        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14047        longTmp[0] = 0;
14048        Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
14049                SINGLE_LONG_FORMAT, null, longTmp, null);
14050        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14051        longTmp[0] = 0;
14052        Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
14053                SINGLE_LONG_FORMAT, null, longTmp, null);
14054        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14055        longTmp[0] = 0;
14056        Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
14057                SINGLE_LONG_FORMAT, null, longTmp, null);
14058        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14059        return longOut;
14060    }
14061
14062    final void dumpApplicationMemoryUsage(FileDescriptor fd,
14063            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
14064        boolean dumpDetails = false;
14065        boolean dumpFullDetails = false;
14066        boolean dumpDalvik = false;
14067        boolean oomOnly = false;
14068        boolean isCompact = false;
14069        boolean localOnly = false;
14070        boolean packages = false;
14071
14072        int opti = 0;
14073        while (opti < args.length) {
14074            String opt = args[opti];
14075            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
14076                break;
14077            }
14078            opti++;
14079            if ("-a".equals(opt)) {
14080                dumpDetails = true;
14081                dumpFullDetails = true;
14082                dumpDalvik = true;
14083            } else if ("-d".equals(opt)) {
14084                dumpDalvik = true;
14085            } else if ("-c".equals(opt)) {
14086                isCompact = true;
14087            } else if ("--oom".equals(opt)) {
14088                oomOnly = true;
14089            } else if ("--local".equals(opt)) {
14090                localOnly = true;
14091            } else if ("--package".equals(opt)) {
14092                packages = true;
14093            } else if ("-h".equals(opt)) {
14094                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
14095                pw.println("  -a: include all available information for each process.");
14096                pw.println("  -d: include dalvik details when dumping process details.");
14097                pw.println("  -c: dump in a compact machine-parseable representation.");
14098                pw.println("  --oom: only show processes organized by oom adj.");
14099                pw.println("  --local: only collect details locally, don't call process.");
14100                pw.println("  --package: interpret process arg as package, dumping all");
14101                pw.println("             processes that have loaded that package.");
14102                pw.println("If [process] is specified it can be the name or ");
14103                pw.println("pid of a specific process to dump.");
14104                return;
14105            } else {
14106                pw.println("Unknown argument: " + opt + "; use -h for help");
14107            }
14108        }
14109
14110        final boolean isCheckinRequest = scanArgs(args, "--checkin");
14111        long uptime = SystemClock.uptimeMillis();
14112        long realtime = SystemClock.elapsedRealtime();
14113        final long[] tmpLong = new long[1];
14114
14115        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
14116        if (procs == null) {
14117            // No Java processes.  Maybe they want to print a native process.
14118            if (args != null && args.length > opti
14119                    && args[opti].charAt(0) != '-') {
14120                ArrayList<ProcessCpuTracker.Stats> nativeProcs
14121                        = new ArrayList<ProcessCpuTracker.Stats>();
14122                updateCpuStatsNow();
14123                int findPid = -1;
14124                try {
14125                    findPid = Integer.parseInt(args[opti]);
14126                } catch (NumberFormatException e) {
14127                }
14128                synchronized (mProcessCpuTracker) {
14129                    final int N = mProcessCpuTracker.countStats();
14130                    for (int i=0; i<N; i++) {
14131                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14132                        if (st.pid == findPid || (st.baseName != null
14133                                && st.baseName.equals(args[opti]))) {
14134                            nativeProcs.add(st);
14135                        }
14136                    }
14137                }
14138                if (nativeProcs.size() > 0) {
14139                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
14140                            isCompact);
14141                    Debug.MemoryInfo mi = null;
14142                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
14143                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
14144                        final int pid = r.pid;
14145                        if (!isCheckinRequest && dumpDetails) {
14146                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
14147                        }
14148                        if (mi == null) {
14149                            mi = new Debug.MemoryInfo();
14150                        }
14151                        if (dumpDetails || (!brief && !oomOnly)) {
14152                            Debug.getMemoryInfo(pid, mi);
14153                        } else {
14154                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
14155                            mi.dalvikPrivateDirty = (int)tmpLong[0];
14156                        }
14157                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
14158                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
14159                        if (isCheckinRequest) {
14160                            pw.println();
14161                        }
14162                    }
14163                    return;
14164                }
14165            }
14166            pw.println("No process found for: " + args[opti]);
14167            return;
14168        }
14169
14170        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
14171            dumpDetails = true;
14172        }
14173
14174        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
14175
14176        String[] innerArgs = new String[args.length-opti];
14177        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
14178
14179        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
14180        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
14181        long nativePss = 0;
14182        long dalvikPss = 0;
14183        long otherPss = 0;
14184        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
14185
14186        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
14187        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
14188                new ArrayList[DUMP_MEM_OOM_LABEL.length];
14189
14190        long totalPss = 0;
14191        long cachedPss = 0;
14192
14193        Debug.MemoryInfo mi = null;
14194        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
14195            final ProcessRecord r = procs.get(i);
14196            final IApplicationThread thread;
14197            final int pid;
14198            final int oomAdj;
14199            final boolean hasActivities;
14200            synchronized (this) {
14201                thread = r.thread;
14202                pid = r.pid;
14203                oomAdj = r.getSetAdjWithServices();
14204                hasActivities = r.activities.size() > 0;
14205            }
14206            if (thread != null) {
14207                if (!isCheckinRequest && dumpDetails) {
14208                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
14209                }
14210                if (mi == null) {
14211                    mi = new Debug.MemoryInfo();
14212                }
14213                if (dumpDetails || (!brief && !oomOnly)) {
14214                    Debug.getMemoryInfo(pid, mi);
14215                } else {
14216                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
14217                    mi.dalvikPrivateDirty = (int)tmpLong[0];
14218                }
14219                if (dumpDetails) {
14220                    if (localOnly) {
14221                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
14222                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
14223                        if (isCheckinRequest) {
14224                            pw.println();
14225                        }
14226                    } else {
14227                        try {
14228                            pw.flush();
14229                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
14230                                    dumpDalvik, innerArgs);
14231                        } catch (RemoteException e) {
14232                            if (!isCheckinRequest) {
14233                                pw.println("Got RemoteException!");
14234                                pw.flush();
14235                            }
14236                        }
14237                    }
14238                }
14239
14240                final long myTotalPss = mi.getTotalPss();
14241                final long myTotalUss = mi.getTotalUss();
14242
14243                synchronized (this) {
14244                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
14245                        // Record this for posterity if the process has been stable.
14246                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
14247                    }
14248                }
14249
14250                if (!isCheckinRequest && mi != null) {
14251                    totalPss += myTotalPss;
14252                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
14253                            (hasActivities ? " / activities)" : ")"),
14254                            r.processName, myTotalPss, pid, hasActivities);
14255                    procMems.add(pssItem);
14256                    procMemsMap.put(pid, pssItem);
14257
14258                    nativePss += mi.nativePss;
14259                    dalvikPss += mi.dalvikPss;
14260                    otherPss += mi.otherPss;
14261                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14262                        long mem = mi.getOtherPss(j);
14263                        miscPss[j] += mem;
14264                        otherPss -= mem;
14265                    }
14266
14267                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
14268                        cachedPss += myTotalPss;
14269                    }
14270
14271                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
14272                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
14273                                || oomIndex == (oomPss.length-1)) {
14274                            oomPss[oomIndex] += myTotalPss;
14275                            if (oomProcs[oomIndex] == null) {
14276                                oomProcs[oomIndex] = new ArrayList<MemItem>();
14277                            }
14278                            oomProcs[oomIndex].add(pssItem);
14279                            break;
14280                        }
14281                    }
14282                }
14283            }
14284        }
14285
14286        long nativeProcTotalPss = 0;
14287
14288        if (!isCheckinRequest && procs.size() > 1 && !packages) {
14289            // If we are showing aggregations, also look for native processes to
14290            // include so that our aggregations are more accurate.
14291            updateCpuStatsNow();
14292            mi = null;
14293            synchronized (mProcessCpuTracker) {
14294                final int N = mProcessCpuTracker.countStats();
14295                for (int i=0; i<N; i++) {
14296                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14297                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
14298                        if (mi == null) {
14299                            mi = new Debug.MemoryInfo();
14300                        }
14301                        if (!brief && !oomOnly) {
14302                            Debug.getMemoryInfo(st.pid, mi);
14303                        } else {
14304                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
14305                            mi.nativePrivateDirty = (int)tmpLong[0];
14306                        }
14307
14308                        final long myTotalPss = mi.getTotalPss();
14309                        totalPss += myTotalPss;
14310                        nativeProcTotalPss += myTotalPss;
14311
14312                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
14313                                st.name, myTotalPss, st.pid, false);
14314                        procMems.add(pssItem);
14315
14316                        nativePss += mi.nativePss;
14317                        dalvikPss += mi.dalvikPss;
14318                        otherPss += mi.otherPss;
14319                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14320                            long mem = mi.getOtherPss(j);
14321                            miscPss[j] += mem;
14322                            otherPss -= mem;
14323                        }
14324                        oomPss[0] += myTotalPss;
14325                        if (oomProcs[0] == null) {
14326                            oomProcs[0] = new ArrayList<MemItem>();
14327                        }
14328                        oomProcs[0].add(pssItem);
14329                    }
14330                }
14331            }
14332
14333            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
14334
14335            catMems.add(new MemItem("Native", "Native", nativePss, -1));
14336            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
14337            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
14338            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14339                String label = Debug.MemoryInfo.getOtherLabel(j);
14340                catMems.add(new MemItem(label, label, miscPss[j], j));
14341            }
14342
14343            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
14344            for (int j=0; j<oomPss.length; j++) {
14345                if (oomPss[j] != 0) {
14346                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
14347                            : DUMP_MEM_OOM_LABEL[j];
14348                    MemItem item = new MemItem(label, label, oomPss[j],
14349                            DUMP_MEM_OOM_ADJ[j]);
14350                    item.subitems = oomProcs[j];
14351                    oomMems.add(item);
14352                }
14353            }
14354
14355            if (!brief && !oomOnly && !isCompact) {
14356                pw.println();
14357                pw.println("Total PSS by process:");
14358                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
14359                pw.println();
14360            }
14361            if (!isCompact) {
14362                pw.println("Total PSS by OOM adjustment:");
14363            }
14364            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
14365            if (!brief && !oomOnly) {
14366                PrintWriter out = categoryPw != null ? categoryPw : pw;
14367                if (!isCompact) {
14368                    out.println();
14369                    out.println("Total PSS by category:");
14370                }
14371                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
14372            }
14373            if (!isCompact) {
14374                pw.println();
14375            }
14376            MemInfoReader memInfo = new MemInfoReader();
14377            memInfo.readMemInfo();
14378            if (nativeProcTotalPss > 0) {
14379                synchronized (this) {
14380                    mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
14381                            memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
14382                            memInfo.getKernelUsedSizeKb(), nativeProcTotalPss);
14383                }
14384            }
14385            if (!brief) {
14386                if (!isCompact) {
14387                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
14388                    pw.print(" kB (status ");
14389                    switch (mLastMemoryLevel) {
14390                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
14391                            pw.println("normal)");
14392                            break;
14393                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
14394                            pw.println("moderate)");
14395                            break;
14396                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
14397                            pw.println("low)");
14398                            break;
14399                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
14400                            pw.println("critical)");
14401                            break;
14402                        default:
14403                            pw.print(mLastMemoryLevel);
14404                            pw.println(")");
14405                            break;
14406                    }
14407                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
14408                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
14409                            pw.print(cachedPss); pw.print(" cached pss + ");
14410                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached kernel + ");
14411                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
14412                } else {
14413                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
14414                    pw.print(cachedPss + memInfo.getCachedSizeKb()
14415                            + memInfo.getFreeSizeKb()); pw.print(",");
14416                    pw.println(totalPss - cachedPss);
14417                }
14418            }
14419            if (!isCompact) {
14420                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
14421                        + memInfo.getKernelUsedSizeKb()); pw.print(" kB (");
14422                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
14423                        pw.print(memInfo.getKernelUsedSizeKb()); pw.print(" kernel)\n");
14424                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
14425                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
14426                        - memInfo.getKernelUsedSizeKb()); pw.println(" kB");
14427            }
14428            if (!brief) {
14429                if (memInfo.getZramTotalSizeKb() != 0) {
14430                    if (!isCompact) {
14431                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
14432                                pw.print(" kB physical used for ");
14433                                pw.print(memInfo.getSwapTotalSizeKb()
14434                                        - memInfo.getSwapFreeSizeKb());
14435                                pw.print(" kB in swap (");
14436                                pw.print(memInfo.getSwapTotalSizeKb());
14437                                pw.println(" kB total swap)");
14438                    } else {
14439                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
14440                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
14441                                pw.println(memInfo.getSwapFreeSizeKb());
14442                    }
14443                }
14444                final long[] ksm = getKsmInfo();
14445                if (!isCompact) {
14446                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
14447                            || ksm[KSM_VOLATILE] != 0) {
14448                        pw.print("      KSM: "); pw.print(ksm[KSM_SHARING]);
14449                                pw.print(" kB saved from shared ");
14450                                pw.print(ksm[KSM_SHARED]); pw.println(" kB");
14451                        pw.print("           "); pw.print(ksm[KSM_UNSHARED]);
14452                                pw.print(" kB unshared; ");
14453                                pw.print(ksm[KSM_VOLATILE]); pw.println(" kB volatile");
14454                    }
14455                    pw.print("   Tuning: ");
14456                    pw.print(ActivityManager.staticGetMemoryClass());
14457                    pw.print(" (large ");
14458                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14459                    pw.print("), oom ");
14460                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14461                    pw.print(" kB");
14462                    pw.print(", restore limit ");
14463                    pw.print(mProcessList.getCachedRestoreThresholdKb());
14464                    pw.print(" kB");
14465                    if (ActivityManager.isLowRamDeviceStatic()) {
14466                        pw.print(" (low-ram)");
14467                    }
14468                    if (ActivityManager.isHighEndGfx()) {
14469                        pw.print(" (high-end-gfx)");
14470                    }
14471                    pw.println();
14472                } else {
14473                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
14474                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
14475                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
14476                    pw.print("tuning,");
14477                    pw.print(ActivityManager.staticGetMemoryClass());
14478                    pw.print(',');
14479                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14480                    pw.print(',');
14481                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14482                    if (ActivityManager.isLowRamDeviceStatic()) {
14483                        pw.print(",low-ram");
14484                    }
14485                    if (ActivityManager.isHighEndGfx()) {
14486                        pw.print(",high-end-gfx");
14487                    }
14488                    pw.println();
14489                }
14490            }
14491        }
14492    }
14493
14494    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
14495            long memtrack, String name) {
14496        sb.append("  ");
14497        sb.append(ProcessList.makeOomAdjString(oomAdj));
14498        sb.append(' ');
14499        sb.append(ProcessList.makeProcStateString(procState));
14500        sb.append(' ');
14501        ProcessList.appendRamKb(sb, pss);
14502        sb.append(" kB: ");
14503        sb.append(name);
14504        if (memtrack > 0) {
14505            sb.append(" (");
14506            sb.append(memtrack);
14507            sb.append(" kB memtrack)");
14508        }
14509    }
14510
14511    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
14512        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
14513        sb.append(" (pid ");
14514        sb.append(mi.pid);
14515        sb.append(") ");
14516        sb.append(mi.adjType);
14517        sb.append('\n');
14518        if (mi.adjReason != null) {
14519            sb.append("                      ");
14520            sb.append(mi.adjReason);
14521            sb.append('\n');
14522        }
14523    }
14524
14525    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
14526        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
14527        for (int i=0, N=memInfos.size(); i<N; i++) {
14528            ProcessMemInfo mi = memInfos.get(i);
14529            infoMap.put(mi.pid, mi);
14530        }
14531        updateCpuStatsNow();
14532        long[] memtrackTmp = new long[1];
14533        synchronized (mProcessCpuTracker) {
14534            final int N = mProcessCpuTracker.countStats();
14535            for (int i=0; i<N; i++) {
14536                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14537                if (st.vsize > 0) {
14538                    long pss = Debug.getPss(st.pid, null, memtrackTmp);
14539                    if (pss > 0) {
14540                        if (infoMap.indexOfKey(st.pid) < 0) {
14541                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
14542                                    ProcessList.NATIVE_ADJ, -1, "native", null);
14543                            mi.pss = pss;
14544                            mi.memtrack = memtrackTmp[0];
14545                            memInfos.add(mi);
14546                        }
14547                    }
14548                }
14549            }
14550        }
14551
14552        long totalPss = 0;
14553        long totalMemtrack = 0;
14554        for (int i=0, N=memInfos.size(); i<N; i++) {
14555            ProcessMemInfo mi = memInfos.get(i);
14556            if (mi.pss == 0) {
14557                mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
14558                mi.memtrack = memtrackTmp[0];
14559            }
14560            totalPss += mi.pss;
14561            totalMemtrack += mi.memtrack;
14562        }
14563        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
14564            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
14565                if (lhs.oomAdj != rhs.oomAdj) {
14566                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
14567                }
14568                if (lhs.pss != rhs.pss) {
14569                    return lhs.pss < rhs.pss ? 1 : -1;
14570                }
14571                return 0;
14572            }
14573        });
14574
14575        StringBuilder tag = new StringBuilder(128);
14576        StringBuilder stack = new StringBuilder(128);
14577        tag.append("Low on memory -- ");
14578        appendMemBucket(tag, totalPss, "total", false);
14579        appendMemBucket(stack, totalPss, "total", true);
14580
14581        StringBuilder fullNativeBuilder = new StringBuilder(1024);
14582        StringBuilder shortNativeBuilder = new StringBuilder(1024);
14583        StringBuilder fullJavaBuilder = new StringBuilder(1024);
14584
14585        boolean firstLine = true;
14586        int lastOomAdj = Integer.MIN_VALUE;
14587        long extraNativeRam = 0;
14588        long extraNativeMemtrack = 0;
14589        long cachedPss = 0;
14590        for (int i=0, N=memInfos.size(); i<N; i++) {
14591            ProcessMemInfo mi = memInfos.get(i);
14592
14593            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
14594                cachedPss += mi.pss;
14595            }
14596
14597            if (mi.oomAdj != ProcessList.NATIVE_ADJ
14598                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
14599                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
14600                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
14601                if (lastOomAdj != mi.oomAdj) {
14602                    lastOomAdj = mi.oomAdj;
14603                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14604                        tag.append(" / ");
14605                    }
14606                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
14607                        if (firstLine) {
14608                            stack.append(":");
14609                            firstLine = false;
14610                        }
14611                        stack.append("\n\t at ");
14612                    } else {
14613                        stack.append("$");
14614                    }
14615                } else {
14616                    tag.append(" ");
14617                    stack.append("$");
14618                }
14619                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14620                    appendMemBucket(tag, mi.pss, mi.name, false);
14621                }
14622                appendMemBucket(stack, mi.pss, mi.name, true);
14623                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
14624                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
14625                    stack.append("(");
14626                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
14627                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
14628                            stack.append(DUMP_MEM_OOM_LABEL[k]);
14629                            stack.append(":");
14630                            stack.append(DUMP_MEM_OOM_ADJ[k]);
14631                        }
14632                    }
14633                    stack.append(")");
14634                }
14635            }
14636
14637            appendMemInfo(fullNativeBuilder, mi);
14638            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
14639                // The short form only has native processes that are >= 512K.
14640                if (mi.pss >= 512) {
14641                    appendMemInfo(shortNativeBuilder, mi);
14642                } else {
14643                    extraNativeRam += mi.pss;
14644                    extraNativeMemtrack += mi.memtrack;
14645                }
14646            } else {
14647                // Short form has all other details, but if we have collected RAM
14648                // from smaller native processes let's dump a summary of that.
14649                if (extraNativeRam > 0) {
14650                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
14651                            -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
14652                    shortNativeBuilder.append('\n');
14653                    extraNativeRam = 0;
14654                }
14655                appendMemInfo(fullJavaBuilder, mi);
14656            }
14657        }
14658
14659        fullJavaBuilder.append("           ");
14660        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
14661        fullJavaBuilder.append(" kB: TOTAL");
14662        if (totalMemtrack > 0) {
14663            fullJavaBuilder.append(" (");
14664            fullJavaBuilder.append(totalMemtrack);
14665            fullJavaBuilder.append(" kB memtrack)");
14666        } else {
14667        }
14668        fullJavaBuilder.append("\n");
14669
14670        MemInfoReader memInfo = new MemInfoReader();
14671        memInfo.readMemInfo();
14672        final long[] infos = memInfo.getRawInfo();
14673
14674        StringBuilder memInfoBuilder = new StringBuilder(1024);
14675        Debug.getMemInfo(infos);
14676        memInfoBuilder.append("  MemInfo: ");
14677        memInfoBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
14678        memInfoBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
14679        memInfoBuilder.append(infos[Debug.MEMINFO_VM_ALLOC_USED]).append(" kB vm alloc, ");
14680        memInfoBuilder.append(infos[Debug.MEMINFO_PAGE_TABLES]).append(" kB page tables ");
14681        memInfoBuilder.append(infos[Debug.MEMINFO_KERNEL_STACK]).append(" kB kernel stack\n");
14682        memInfoBuilder.append("           ");
14683        memInfoBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
14684        memInfoBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
14685        memInfoBuilder.append(infos[Debug.MEMINFO_MAPPED]).append(" kB mapped, ");
14686        memInfoBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
14687        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
14688            memInfoBuilder.append("  ZRAM: ");
14689            memInfoBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
14690            memInfoBuilder.append(" kB RAM, ");
14691            memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
14692            memInfoBuilder.append(" kB swap total, ");
14693            memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
14694            memInfoBuilder.append(" kB swap free\n");
14695        }
14696        final long[] ksm = getKsmInfo();
14697        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
14698                || ksm[KSM_VOLATILE] != 0) {
14699            memInfoBuilder.append("  KSM: "); memInfoBuilder.append(ksm[KSM_SHARING]);
14700            memInfoBuilder.append(" kB saved from shared ");
14701            memInfoBuilder.append(ksm[KSM_SHARED]); memInfoBuilder.append(" kB\n");
14702            memInfoBuilder.append("       "); memInfoBuilder.append(ksm[KSM_UNSHARED]);
14703            memInfoBuilder.append(" kB unshared; ");
14704            memInfoBuilder.append(ksm[KSM_VOLATILE]); memInfoBuilder.append(" kB volatile\n");
14705        }
14706        memInfoBuilder.append("  Free RAM: ");
14707        memInfoBuilder.append(cachedPss + memInfo.getCachedSizeKb()
14708                + memInfo.getFreeSizeKb());
14709        memInfoBuilder.append(" kB\n");
14710        memInfoBuilder.append("  Used RAM: ");
14711        memInfoBuilder.append(totalPss - cachedPss + memInfo.getKernelUsedSizeKb());
14712        memInfoBuilder.append(" kB\n");
14713        memInfoBuilder.append("  Lost RAM: ");
14714        memInfoBuilder.append(memInfo.getTotalSizeKb()
14715                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
14716                - memInfo.getKernelUsedSizeKb());
14717        memInfoBuilder.append(" kB\n");
14718        Slog.i(TAG, "Low on memory:");
14719        Slog.i(TAG, shortNativeBuilder.toString());
14720        Slog.i(TAG, fullJavaBuilder.toString());
14721        Slog.i(TAG, memInfoBuilder.toString());
14722
14723        StringBuilder dropBuilder = new StringBuilder(1024);
14724        /*
14725        StringWriter oomSw = new StringWriter();
14726        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
14727        StringWriter catSw = new StringWriter();
14728        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
14729        String[] emptyArgs = new String[] { };
14730        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
14731        oomPw.flush();
14732        String oomString = oomSw.toString();
14733        */
14734        dropBuilder.append("Low on memory:");
14735        dropBuilder.append(stack);
14736        dropBuilder.append('\n');
14737        dropBuilder.append(fullNativeBuilder);
14738        dropBuilder.append(fullJavaBuilder);
14739        dropBuilder.append('\n');
14740        dropBuilder.append(memInfoBuilder);
14741        dropBuilder.append('\n');
14742        /*
14743        dropBuilder.append(oomString);
14744        dropBuilder.append('\n');
14745        */
14746        StringWriter catSw = new StringWriter();
14747        synchronized (ActivityManagerService.this) {
14748            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
14749            String[] emptyArgs = new String[] { };
14750            catPw.println();
14751            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
14752            catPw.println();
14753            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
14754                    false, false, null);
14755            catPw.println();
14756            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
14757            catPw.flush();
14758        }
14759        dropBuilder.append(catSw.toString());
14760        addErrorToDropBox("lowmem", null, "system_server", null,
14761                null, tag.toString(), dropBuilder.toString(), null, null);
14762        //Slog.i(TAG, "Sent to dropbox:");
14763        //Slog.i(TAG, dropBuilder.toString());
14764        synchronized (ActivityManagerService.this) {
14765            long now = SystemClock.uptimeMillis();
14766            if (mLastMemUsageReportTime < now) {
14767                mLastMemUsageReportTime = now;
14768            }
14769        }
14770    }
14771
14772    /**
14773     * Searches array of arguments for the specified string
14774     * @param args array of argument strings
14775     * @param value value to search for
14776     * @return true if the value is contained in the array
14777     */
14778    private static boolean scanArgs(String[] args, String value) {
14779        if (args != null) {
14780            for (String arg : args) {
14781                if (value.equals(arg)) {
14782                    return true;
14783                }
14784            }
14785        }
14786        return false;
14787    }
14788
14789    private final boolean removeDyingProviderLocked(ProcessRecord proc,
14790            ContentProviderRecord cpr, boolean always) {
14791        final boolean inLaunching = mLaunchingProviders.contains(cpr);
14792
14793        if (!inLaunching || always) {
14794            synchronized (cpr) {
14795                cpr.launchingApp = null;
14796                cpr.notifyAll();
14797            }
14798            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
14799            String names[] = cpr.info.authority.split(";");
14800            for (int j = 0; j < names.length; j++) {
14801                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
14802            }
14803        }
14804
14805        for (int i=0; i<cpr.connections.size(); i++) {
14806            ContentProviderConnection conn = cpr.connections.get(i);
14807            if (conn.waiting) {
14808                // If this connection is waiting for the provider, then we don't
14809                // need to mess with its process unless we are always removing
14810                // or for some reason the provider is not currently launching.
14811                if (inLaunching && !always) {
14812                    continue;
14813                }
14814            }
14815            ProcessRecord capp = conn.client;
14816            conn.dead = true;
14817            if (conn.stableCount > 0) {
14818                if (!capp.persistent && capp.thread != null
14819                        && capp.pid != 0
14820                        && capp.pid != MY_PID) {
14821                    capp.kill("depends on provider "
14822                            + cpr.name.flattenToShortString()
14823                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
14824                }
14825            } else if (capp.thread != null && conn.provider.provider != null) {
14826                try {
14827                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
14828                } catch (RemoteException e) {
14829                }
14830                // In the protocol here, we don't expect the client to correctly
14831                // clean up this connection, we'll just remove it.
14832                cpr.connections.remove(i);
14833                if (conn.client.conProviders.remove(conn)) {
14834                    stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
14835                }
14836            }
14837        }
14838
14839        if (inLaunching && always) {
14840            mLaunchingProviders.remove(cpr);
14841        }
14842        return inLaunching;
14843    }
14844
14845    /**
14846     * Main code for cleaning up a process when it has gone away.  This is
14847     * called both as a result of the process dying, or directly when stopping
14848     * a process when running in single process mode.
14849     *
14850     * @return Returns true if the given process has been restarted, so the
14851     * app that was passed in must remain on the process lists.
14852     */
14853    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
14854            boolean restarting, boolean allowRestart, int index) {
14855        if (index >= 0) {
14856            removeLruProcessLocked(app);
14857            ProcessList.remove(app.pid);
14858        }
14859
14860        mProcessesToGc.remove(app);
14861        mPendingPssProcesses.remove(app);
14862
14863        // Dismiss any open dialogs.
14864        if (app.crashDialog != null && !app.forceCrashReport) {
14865            app.crashDialog.dismiss();
14866            app.crashDialog = null;
14867        }
14868        if (app.anrDialog != null) {
14869            app.anrDialog.dismiss();
14870            app.anrDialog = null;
14871        }
14872        if (app.waitDialog != null) {
14873            app.waitDialog.dismiss();
14874            app.waitDialog = null;
14875        }
14876
14877        app.crashing = false;
14878        app.notResponding = false;
14879
14880        app.resetPackageList(mProcessStats);
14881        app.unlinkDeathRecipient();
14882        app.makeInactive(mProcessStats);
14883        app.waitingToKill = null;
14884        app.forcingToForeground = null;
14885        updateProcessForegroundLocked(app, false, false);
14886        app.foregroundActivities = false;
14887        app.hasShownUi = false;
14888        app.treatLikeActivity = false;
14889        app.hasAboveClient = false;
14890        app.hasClientActivities = false;
14891
14892        mServices.killServicesLocked(app, allowRestart);
14893
14894        boolean restart = false;
14895
14896        // Remove published content providers.
14897        for (int i=app.pubProviders.size()-1; i>=0; i--) {
14898            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
14899            final boolean always = app.bad || !allowRestart;
14900            if (removeDyingProviderLocked(app, cpr, always) || always) {
14901                // We left the provider in the launching list, need to
14902                // restart it.
14903                restart = true;
14904            }
14905
14906            cpr.provider = null;
14907            cpr.proc = null;
14908        }
14909        app.pubProviders.clear();
14910
14911        // Take care of any launching providers waiting for this process.
14912        if (checkAppInLaunchingProvidersLocked(app, false)) {
14913            restart = true;
14914        }
14915
14916        // Unregister from connected content providers.
14917        if (!app.conProviders.isEmpty()) {
14918            for (int i=0; i<app.conProviders.size(); i++) {
14919                ContentProviderConnection conn = app.conProviders.get(i);
14920                conn.provider.connections.remove(conn);
14921                stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
14922                        conn.provider.name);
14923            }
14924            app.conProviders.clear();
14925        }
14926
14927        // At this point there may be remaining entries in mLaunchingProviders
14928        // where we were the only one waiting, so they are no longer of use.
14929        // Look for these and clean up if found.
14930        // XXX Commented out for now.  Trying to figure out a way to reproduce
14931        // the actual situation to identify what is actually going on.
14932        if (false) {
14933            for (int i=0; i<mLaunchingProviders.size(); i++) {
14934                ContentProviderRecord cpr = (ContentProviderRecord)
14935                        mLaunchingProviders.get(i);
14936                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
14937                    synchronized (cpr) {
14938                        cpr.launchingApp = null;
14939                        cpr.notifyAll();
14940                    }
14941                }
14942            }
14943        }
14944
14945        skipCurrentReceiverLocked(app);
14946
14947        // Unregister any receivers.
14948        for (int i=app.receivers.size()-1; i>=0; i--) {
14949            removeReceiverLocked(app.receivers.valueAt(i));
14950        }
14951        app.receivers.clear();
14952
14953        // If the app is undergoing backup, tell the backup manager about it
14954        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
14955            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
14956                    + mBackupTarget.appInfo + " died during backup");
14957            try {
14958                IBackupManager bm = IBackupManager.Stub.asInterface(
14959                        ServiceManager.getService(Context.BACKUP_SERVICE));
14960                bm.agentDisconnected(app.info.packageName);
14961            } catch (RemoteException e) {
14962                // can't happen; backup manager is local
14963            }
14964        }
14965
14966        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
14967            ProcessChangeItem item = mPendingProcessChanges.get(i);
14968            if (item.pid == app.pid) {
14969                mPendingProcessChanges.remove(i);
14970                mAvailProcessChanges.add(item);
14971            }
14972        }
14973        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
14974
14975        // If the caller is restarting this app, then leave it in its
14976        // current lists and let the caller take care of it.
14977        if (restarting) {
14978            return false;
14979        }
14980
14981        if (!app.persistent || app.isolated) {
14982            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
14983                    "Removing non-persistent process during cleanup: " + app);
14984            mProcessNames.remove(app.processName, app.uid);
14985            mIsolatedProcesses.remove(app.uid);
14986            if (mHeavyWeightProcess == app) {
14987                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
14988                        mHeavyWeightProcess.userId, 0));
14989                mHeavyWeightProcess = null;
14990            }
14991        } else if (!app.removed) {
14992            // This app is persistent, so we need to keep its record around.
14993            // If it is not already on the pending app list, add it there
14994            // and start a new process for it.
14995            if (mPersistentStartingProcesses.indexOf(app) < 0) {
14996                mPersistentStartingProcesses.add(app);
14997                restart = true;
14998            }
14999        }
15000        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
15001                "Clean-up removing on hold: " + app);
15002        mProcessesOnHold.remove(app);
15003
15004        if (app == mHomeProcess) {
15005            mHomeProcess = null;
15006        }
15007        if (app == mPreviousProcess) {
15008            mPreviousProcess = null;
15009        }
15010
15011        if (restart && !app.isolated) {
15012            // We have components that still need to be running in the
15013            // process, so re-launch it.
15014            if (index < 0) {
15015                ProcessList.remove(app.pid);
15016            }
15017            mProcessNames.put(app.processName, app.uid, app);
15018            startProcessLocked(app, "restart", app.processName);
15019            return true;
15020        } else if (app.pid > 0 && app.pid != MY_PID) {
15021            // Goodbye!
15022            boolean removed;
15023            synchronized (mPidsSelfLocked) {
15024                mPidsSelfLocked.remove(app.pid);
15025                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
15026            }
15027            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
15028            if (app.isolated) {
15029                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
15030            }
15031            app.setPid(0);
15032        }
15033        return false;
15034    }
15035
15036    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
15037        // Look through the content providers we are waiting to have launched,
15038        // and if any run in this process then either schedule a restart of
15039        // the process or kill the client waiting for it if this process has
15040        // gone bad.
15041        int NL = mLaunchingProviders.size();
15042        boolean restart = false;
15043        for (int i=0; i<NL; i++) {
15044            ContentProviderRecord cpr = mLaunchingProviders.get(i);
15045            if (cpr.launchingApp == app) {
15046                if (!alwaysBad && !app.bad) {
15047                    restart = true;
15048                } else {
15049                    removeDyingProviderLocked(app, cpr, true);
15050                    // cpr should have been removed from mLaunchingProviders
15051                    NL = mLaunchingProviders.size();
15052                    i--;
15053                }
15054            }
15055        }
15056        return restart;
15057    }
15058
15059    // =========================================================
15060    // SERVICES
15061    // =========================================================
15062
15063    @Override
15064    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
15065            int flags) {
15066        enforceNotIsolatedCaller("getServices");
15067        synchronized (this) {
15068            return mServices.getRunningServiceInfoLocked(maxNum, flags);
15069        }
15070    }
15071
15072    @Override
15073    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
15074        enforceNotIsolatedCaller("getRunningServiceControlPanel");
15075        synchronized (this) {
15076            return mServices.getRunningServiceControlPanelLocked(name);
15077        }
15078    }
15079
15080    @Override
15081    public ComponentName startService(IApplicationThread caller, Intent service,
15082            String resolvedType, int userId) {
15083        enforceNotIsolatedCaller("startService");
15084        // Refuse possible leaked file descriptors
15085        if (service != null && service.hasFileDescriptors() == true) {
15086            throw new IllegalArgumentException("File descriptors passed in Intent");
15087        }
15088
15089        if (DEBUG_SERVICE)
15090            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
15091        synchronized(this) {
15092            final int callingPid = Binder.getCallingPid();
15093            final int callingUid = Binder.getCallingUid();
15094            final long origId = Binder.clearCallingIdentity();
15095            ComponentName res = mServices.startServiceLocked(caller, service,
15096                    resolvedType, callingPid, callingUid, userId);
15097            Binder.restoreCallingIdentity(origId);
15098            return res;
15099        }
15100    }
15101
15102    ComponentName startServiceInPackage(int uid,
15103            Intent service, String resolvedType, int userId) {
15104        synchronized(this) {
15105            if (DEBUG_SERVICE)
15106                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
15107            final long origId = Binder.clearCallingIdentity();
15108            ComponentName res = mServices.startServiceLocked(null, service,
15109                    resolvedType, -1, uid, userId);
15110            Binder.restoreCallingIdentity(origId);
15111            return res;
15112        }
15113    }
15114
15115    @Override
15116    public int stopService(IApplicationThread caller, Intent service,
15117            String resolvedType, int userId) {
15118        enforceNotIsolatedCaller("stopService");
15119        // Refuse possible leaked file descriptors
15120        if (service != null && service.hasFileDescriptors() == true) {
15121            throw new IllegalArgumentException("File descriptors passed in Intent");
15122        }
15123
15124        synchronized(this) {
15125            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
15126        }
15127    }
15128
15129    @Override
15130    public IBinder peekService(Intent service, String resolvedType) {
15131        enforceNotIsolatedCaller("peekService");
15132        // Refuse possible leaked file descriptors
15133        if (service != null && service.hasFileDescriptors() == true) {
15134            throw new IllegalArgumentException("File descriptors passed in Intent");
15135        }
15136        synchronized(this) {
15137            return mServices.peekServiceLocked(service, resolvedType);
15138        }
15139    }
15140
15141    @Override
15142    public boolean stopServiceToken(ComponentName className, IBinder token,
15143            int startId) {
15144        synchronized(this) {
15145            return mServices.stopServiceTokenLocked(className, token, startId);
15146        }
15147    }
15148
15149    @Override
15150    public void setServiceForeground(ComponentName className, IBinder token,
15151            int id, Notification notification, boolean removeNotification) {
15152        synchronized(this) {
15153            mServices.setServiceForegroundLocked(className, token, id, notification,
15154                    removeNotification);
15155        }
15156    }
15157
15158    @Override
15159    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
15160            boolean requireFull, String name, String callerPackage) {
15161        return handleIncomingUser(callingPid, callingUid, userId, allowAll,
15162                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
15163    }
15164
15165    int unsafeConvertIncomingUser(int userId) {
15166        return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
15167                ? mCurrentUserId : userId;
15168    }
15169
15170    int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
15171            int allowMode, String name, String callerPackage) {
15172        final int callingUserId = UserHandle.getUserId(callingUid);
15173        if (callingUserId == userId) {
15174            return userId;
15175        }
15176
15177        // Note that we may be accessing mCurrentUserId outside of a lock...
15178        // shouldn't be a big deal, if this is being called outside
15179        // of a locked context there is intrinsically a race with
15180        // the value the caller will receive and someone else changing it.
15181        // We assume that USER_CURRENT_OR_SELF will use the current user; later
15182        // we will switch to the calling user if access to the current user fails.
15183        int targetUserId = unsafeConvertIncomingUser(userId);
15184
15185        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
15186            final boolean allow;
15187            if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
15188                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
15189                // If the caller has this permission, they always pass go.  And collect $200.
15190                allow = true;
15191            } else if (allowMode == ALLOW_FULL_ONLY) {
15192                // We require full access, sucks to be you.
15193                allow = false;
15194            } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
15195                    callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
15196                // If the caller does not have either permission, they are always doomed.
15197                allow = false;
15198            } else if (allowMode == ALLOW_NON_FULL) {
15199                // We are blanket allowing non-full access, you lucky caller!
15200                allow = true;
15201            } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
15202                // We may or may not allow this depending on whether the two users are
15203                // in the same profile.
15204                synchronized (mUserProfileGroupIdsSelfLocked) {
15205                    int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
15206                            UserInfo.NO_PROFILE_GROUP_ID);
15207                    int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
15208                            UserInfo.NO_PROFILE_GROUP_ID);
15209                    allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
15210                            && callingProfile == targetProfile;
15211                }
15212            } else {
15213                throw new IllegalArgumentException("Unknown mode: " + allowMode);
15214            }
15215            if (!allow) {
15216                if (userId == UserHandle.USER_CURRENT_OR_SELF) {
15217                    // In this case, they would like to just execute as their
15218                    // owner user instead of failing.
15219                    targetUserId = callingUserId;
15220                } else {
15221                    StringBuilder builder = new StringBuilder(128);
15222                    builder.append("Permission Denial: ");
15223                    builder.append(name);
15224                    if (callerPackage != null) {
15225                        builder.append(" from ");
15226                        builder.append(callerPackage);
15227                    }
15228                    builder.append(" asks to run as user ");
15229                    builder.append(userId);
15230                    builder.append(" but is calling from user ");
15231                    builder.append(UserHandle.getUserId(callingUid));
15232                    builder.append("; this requires ");
15233                    builder.append(INTERACT_ACROSS_USERS_FULL);
15234                    if (allowMode != ALLOW_FULL_ONLY) {
15235                        builder.append(" or ");
15236                        builder.append(INTERACT_ACROSS_USERS);
15237                    }
15238                    String msg = builder.toString();
15239                    Slog.w(TAG, msg);
15240                    throw new SecurityException(msg);
15241                }
15242            }
15243        }
15244        if (!allowAll && targetUserId < 0) {
15245            throw new IllegalArgumentException(
15246                    "Call does not support special user #" + targetUserId);
15247        }
15248        // Check shell permission
15249        if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) {
15250            if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES,
15251                    targetUserId)) {
15252                throw new SecurityException("Shell does not have permission to access user "
15253                        + targetUserId + "\n " + Debug.getCallers(3));
15254            }
15255        }
15256        return targetUserId;
15257    }
15258
15259    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
15260            String className, int flags) {
15261        boolean result = false;
15262        // For apps that don't have pre-defined UIDs, check for permission
15263        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
15264            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
15265                if (ActivityManager.checkUidPermission(
15266                        INTERACT_ACROSS_USERS,
15267                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
15268                    ComponentName comp = new ComponentName(aInfo.packageName, className);
15269                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
15270                            + " requests FLAG_SINGLE_USER, but app does not hold "
15271                            + INTERACT_ACROSS_USERS;
15272                    Slog.w(TAG, msg);
15273                    throw new SecurityException(msg);
15274                }
15275                // Permission passed
15276                result = true;
15277            }
15278        } else if ("system".equals(componentProcessName)) {
15279            result = true;
15280        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
15281            // Phone app and persistent apps are allowed to export singleuser providers.
15282            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
15283                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
15284        }
15285        if (DEBUG_MU) {
15286            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
15287                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
15288        }
15289        return result;
15290    }
15291
15292    /**
15293     * Checks to see if the caller is in the same app as the singleton
15294     * component, or the component is in a special app. It allows special apps
15295     * to export singleton components but prevents exporting singleton
15296     * components for regular apps.
15297     */
15298    boolean isValidSingletonCall(int callingUid, int componentUid) {
15299        int componentAppId = UserHandle.getAppId(componentUid);
15300        return UserHandle.isSameApp(callingUid, componentUid)
15301                || componentAppId == Process.SYSTEM_UID
15302                || componentAppId == Process.PHONE_UID
15303                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
15304                        == PackageManager.PERMISSION_GRANTED;
15305    }
15306
15307    public int bindService(IApplicationThread caller, IBinder token,
15308            Intent service, String resolvedType,
15309            IServiceConnection connection, int flags, int userId) {
15310        enforceNotIsolatedCaller("bindService");
15311
15312        // Refuse possible leaked file descriptors
15313        if (service != null && service.hasFileDescriptors() == true) {
15314            throw new IllegalArgumentException("File descriptors passed in Intent");
15315        }
15316
15317        synchronized(this) {
15318            return mServices.bindServiceLocked(caller, token, service, resolvedType,
15319                    connection, flags, userId);
15320        }
15321    }
15322
15323    public boolean unbindService(IServiceConnection connection) {
15324        synchronized (this) {
15325            return mServices.unbindServiceLocked(connection);
15326        }
15327    }
15328
15329    public void publishService(IBinder token, Intent intent, IBinder service) {
15330        // Refuse possible leaked file descriptors
15331        if (intent != null && intent.hasFileDescriptors() == true) {
15332            throw new IllegalArgumentException("File descriptors passed in Intent");
15333        }
15334
15335        synchronized(this) {
15336            if (!(token instanceof ServiceRecord)) {
15337                throw new IllegalArgumentException("Invalid service token");
15338            }
15339            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
15340        }
15341    }
15342
15343    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
15344        // Refuse possible leaked file descriptors
15345        if (intent != null && intent.hasFileDescriptors() == true) {
15346            throw new IllegalArgumentException("File descriptors passed in Intent");
15347        }
15348
15349        synchronized(this) {
15350            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
15351        }
15352    }
15353
15354    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
15355        synchronized(this) {
15356            if (!(token instanceof ServiceRecord)) {
15357                Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
15358                throw new IllegalArgumentException("Invalid service token");
15359            }
15360            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
15361        }
15362    }
15363
15364    // =========================================================
15365    // BACKUP AND RESTORE
15366    // =========================================================
15367
15368    // Cause the target app to be launched if necessary and its backup agent
15369    // instantiated.  The backup agent will invoke backupAgentCreated() on the
15370    // activity manager to announce its creation.
15371    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
15372        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
15373        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
15374
15375        synchronized(this) {
15376            // !!! TODO: currently no check here that we're already bound
15377            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
15378            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15379            synchronized (stats) {
15380                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
15381            }
15382
15383            // Backup agent is now in use, its package can't be stopped.
15384            try {
15385                AppGlobals.getPackageManager().setPackageStoppedState(
15386                        app.packageName, false, UserHandle.getUserId(app.uid));
15387            } catch (RemoteException e) {
15388            } catch (IllegalArgumentException e) {
15389                Slog.w(TAG, "Failed trying to unstop package "
15390                        + app.packageName + ": " + e);
15391            }
15392
15393            BackupRecord r = new BackupRecord(ss, app, backupMode);
15394            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
15395                    ? new ComponentName(app.packageName, app.backupAgentName)
15396                    : new ComponentName("android", "FullBackupAgent");
15397            // startProcessLocked() returns existing proc's record if it's already running
15398            ProcessRecord proc = startProcessLocked(app.processName, app,
15399                    false, 0, "backup", hostingName, false, false, false);
15400            if (proc == null) {
15401                Slog.e(TAG, "Unable to start backup agent process " + r);
15402                return false;
15403            }
15404
15405            r.app = proc;
15406            mBackupTarget = r;
15407            mBackupAppName = app.packageName;
15408
15409            // Try not to kill the process during backup
15410            updateOomAdjLocked(proc);
15411
15412            // If the process is already attached, schedule the creation of the backup agent now.
15413            // If it is not yet live, this will be done when it attaches to the framework.
15414            if (proc.thread != null) {
15415                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
15416                try {
15417                    proc.thread.scheduleCreateBackupAgent(app,
15418                            compatibilityInfoForPackageLocked(app), backupMode);
15419                } catch (RemoteException e) {
15420                    // Will time out on the backup manager side
15421                }
15422            } else {
15423                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
15424            }
15425            // Invariants: at this point, the target app process exists and the application
15426            // is either already running or in the process of coming up.  mBackupTarget and
15427            // mBackupAppName describe the app, so that when it binds back to the AM we
15428            // know that it's scheduled for a backup-agent operation.
15429        }
15430
15431        return true;
15432    }
15433
15434    @Override
15435    public void clearPendingBackup() {
15436        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
15437        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
15438
15439        synchronized (this) {
15440            mBackupTarget = null;
15441            mBackupAppName = null;
15442        }
15443    }
15444
15445    // A backup agent has just come up
15446    public void backupAgentCreated(String agentPackageName, IBinder agent) {
15447        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
15448                + " = " + agent);
15449
15450        synchronized(this) {
15451            if (!agentPackageName.equals(mBackupAppName)) {
15452                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
15453                return;
15454            }
15455        }
15456
15457        long oldIdent = Binder.clearCallingIdentity();
15458        try {
15459            IBackupManager bm = IBackupManager.Stub.asInterface(
15460                    ServiceManager.getService(Context.BACKUP_SERVICE));
15461            bm.agentConnected(agentPackageName, agent);
15462        } catch (RemoteException e) {
15463            // can't happen; the backup manager service is local
15464        } catch (Exception e) {
15465            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
15466            e.printStackTrace();
15467        } finally {
15468            Binder.restoreCallingIdentity(oldIdent);
15469        }
15470    }
15471
15472    // done with this agent
15473    public void unbindBackupAgent(ApplicationInfo appInfo) {
15474        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
15475        if (appInfo == null) {
15476            Slog.w(TAG, "unbind backup agent for null app");
15477            return;
15478        }
15479
15480        synchronized(this) {
15481            try {
15482                if (mBackupAppName == null) {
15483                    Slog.w(TAG, "Unbinding backup agent with no active backup");
15484                    return;
15485                }
15486
15487                if (!mBackupAppName.equals(appInfo.packageName)) {
15488                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
15489                    return;
15490                }
15491
15492                // Not backing this app up any more; reset its OOM adjustment
15493                final ProcessRecord proc = mBackupTarget.app;
15494                updateOomAdjLocked(proc);
15495
15496                // If the app crashed during backup, 'thread' will be null here
15497                if (proc.thread != null) {
15498                    try {
15499                        proc.thread.scheduleDestroyBackupAgent(appInfo,
15500                                compatibilityInfoForPackageLocked(appInfo));
15501                    } catch (Exception e) {
15502                        Slog.e(TAG, "Exception when unbinding backup agent:");
15503                        e.printStackTrace();
15504                    }
15505                }
15506            } finally {
15507                mBackupTarget = null;
15508                mBackupAppName = null;
15509            }
15510        }
15511    }
15512    // =========================================================
15513    // BROADCASTS
15514    // =========================================================
15515
15516    private final List getStickiesLocked(String action, IntentFilter filter,
15517            List cur, int userId) {
15518        final ContentResolver resolver = mContext.getContentResolver();
15519        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15520        if (stickies == null) {
15521            return cur;
15522        }
15523        final ArrayList<Intent> list = stickies.get(action);
15524        if (list == null) {
15525            return cur;
15526        }
15527        int N = list.size();
15528        for (int i=0; i<N; i++) {
15529            Intent intent = list.get(i);
15530            if (filter.match(resolver, intent, true, TAG) >= 0) {
15531                if (cur == null) {
15532                    cur = new ArrayList<Intent>();
15533                }
15534                cur.add(intent);
15535            }
15536        }
15537        return cur;
15538    }
15539
15540    boolean isPendingBroadcastProcessLocked(int pid) {
15541        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
15542                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
15543    }
15544
15545    void skipPendingBroadcastLocked(int pid) {
15546            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
15547            for (BroadcastQueue queue : mBroadcastQueues) {
15548                queue.skipPendingBroadcastLocked(pid);
15549            }
15550    }
15551
15552    // The app just attached; send any pending broadcasts that it should receive
15553    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
15554        boolean didSomething = false;
15555        for (BroadcastQueue queue : mBroadcastQueues) {
15556            didSomething |= queue.sendPendingBroadcastsLocked(app);
15557        }
15558        return didSomething;
15559    }
15560
15561    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
15562            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
15563        enforceNotIsolatedCaller("registerReceiver");
15564        int callingUid;
15565        int callingPid;
15566        synchronized(this) {
15567            ProcessRecord callerApp = null;
15568            if (caller != null) {
15569                callerApp = getRecordForAppLocked(caller);
15570                if (callerApp == null) {
15571                    throw new SecurityException(
15572                            "Unable to find app for caller " + caller
15573                            + " (pid=" + Binder.getCallingPid()
15574                            + ") when registering receiver " + receiver);
15575                }
15576                if (callerApp.info.uid != Process.SYSTEM_UID &&
15577                        !callerApp.pkgList.containsKey(callerPackage) &&
15578                        !"android".equals(callerPackage)) {
15579                    throw new SecurityException("Given caller package " + callerPackage
15580                            + " is not running in process " + callerApp);
15581                }
15582                callingUid = callerApp.info.uid;
15583                callingPid = callerApp.pid;
15584            } else {
15585                callerPackage = null;
15586                callingUid = Binder.getCallingUid();
15587                callingPid = Binder.getCallingPid();
15588            }
15589
15590            userId = this.handleIncomingUser(callingPid, callingUid, userId,
15591                    true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
15592
15593            List allSticky = null;
15594
15595            // Look for any matching sticky broadcasts...
15596            Iterator actions = filter.actionsIterator();
15597            if (actions != null) {
15598                while (actions.hasNext()) {
15599                    String action = (String)actions.next();
15600                    allSticky = getStickiesLocked(action, filter, allSticky,
15601                            UserHandle.USER_ALL);
15602                    allSticky = getStickiesLocked(action, filter, allSticky,
15603                            UserHandle.getUserId(callingUid));
15604                }
15605            } else {
15606                allSticky = getStickiesLocked(null, filter, allSticky,
15607                        UserHandle.USER_ALL);
15608                allSticky = getStickiesLocked(null, filter, allSticky,
15609                        UserHandle.getUserId(callingUid));
15610            }
15611
15612            // The first sticky in the list is returned directly back to
15613            // the client.
15614            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
15615
15616            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
15617                    + ": " + sticky);
15618
15619            if (receiver == null) {
15620                return sticky;
15621            }
15622
15623            ReceiverList rl
15624                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
15625            if (rl == null) {
15626                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
15627                        userId, receiver);
15628                if (rl.app != null) {
15629                    rl.app.receivers.add(rl);
15630                } else {
15631                    try {
15632                        receiver.asBinder().linkToDeath(rl, 0);
15633                    } catch (RemoteException e) {
15634                        return sticky;
15635                    }
15636                    rl.linkedToDeath = true;
15637                }
15638                mRegisteredReceivers.put(receiver.asBinder(), rl);
15639            } else if (rl.uid != callingUid) {
15640                throw new IllegalArgumentException(
15641                        "Receiver requested to register for uid " + callingUid
15642                        + " was previously registered for uid " + rl.uid);
15643            } else if (rl.pid != callingPid) {
15644                throw new IllegalArgumentException(
15645                        "Receiver requested to register for pid " + callingPid
15646                        + " was previously registered for pid " + rl.pid);
15647            } else if (rl.userId != userId) {
15648                throw new IllegalArgumentException(
15649                        "Receiver requested to register for user " + userId
15650                        + " was previously registered for user " + rl.userId);
15651            }
15652            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
15653                    permission, callingUid, userId);
15654            rl.add(bf);
15655            if (!bf.debugCheck()) {
15656                Slog.w(TAG, "==> For Dynamic broadast");
15657            }
15658            mReceiverResolver.addFilter(bf);
15659
15660            // Enqueue broadcasts for all existing stickies that match
15661            // this filter.
15662            if (allSticky != null) {
15663                ArrayList receivers = new ArrayList();
15664                receivers.add(bf);
15665
15666                int N = allSticky.size();
15667                for (int i=0; i<N; i++) {
15668                    Intent intent = (Intent)allSticky.get(i);
15669                    BroadcastQueue queue = broadcastQueueForIntent(intent);
15670                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
15671                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
15672                            null, null, false, true, true, -1);
15673                    queue.enqueueParallelBroadcastLocked(r);
15674                    queue.scheduleBroadcastsLocked();
15675                }
15676            }
15677
15678            return sticky;
15679        }
15680    }
15681
15682    public void unregisterReceiver(IIntentReceiver receiver) {
15683        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
15684
15685        final long origId = Binder.clearCallingIdentity();
15686        try {
15687            boolean doTrim = false;
15688
15689            synchronized(this) {
15690                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
15691                if (rl != null) {
15692                    if (rl.curBroadcast != null) {
15693                        BroadcastRecord r = rl.curBroadcast;
15694                        final boolean doNext = finishReceiverLocked(
15695                                receiver.asBinder(), r.resultCode, r.resultData,
15696                                r.resultExtras, r.resultAbort);
15697                        if (doNext) {
15698                            doTrim = true;
15699                            r.queue.processNextBroadcast(false);
15700                        }
15701                    }
15702
15703                    if (rl.app != null) {
15704                        rl.app.receivers.remove(rl);
15705                    }
15706                    removeReceiverLocked(rl);
15707                    if (rl.linkedToDeath) {
15708                        rl.linkedToDeath = false;
15709                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
15710                    }
15711                }
15712            }
15713
15714            // If we actually concluded any broadcasts, we might now be able
15715            // to trim the recipients' apps from our working set
15716            if (doTrim) {
15717                trimApplications();
15718                return;
15719            }
15720
15721        } finally {
15722            Binder.restoreCallingIdentity(origId);
15723        }
15724    }
15725
15726    void removeReceiverLocked(ReceiverList rl) {
15727        mRegisteredReceivers.remove(rl.receiver.asBinder());
15728        int N = rl.size();
15729        for (int i=0; i<N; i++) {
15730            mReceiverResolver.removeFilter(rl.get(i));
15731        }
15732    }
15733
15734    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
15735        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
15736            ProcessRecord r = mLruProcesses.get(i);
15737            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
15738                try {
15739                    r.thread.dispatchPackageBroadcast(cmd, packages);
15740                } catch (RemoteException ex) {
15741                }
15742            }
15743        }
15744    }
15745
15746    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
15747            int callingUid, int[] users) {
15748        List<ResolveInfo> receivers = null;
15749        try {
15750            HashSet<ComponentName> singleUserReceivers = null;
15751            boolean scannedFirstReceivers = false;
15752            for (int user : users) {
15753                // Skip users that have Shell restrictions
15754                if (callingUid == Process.SHELL_UID
15755                        && getUserManagerLocked().hasUserRestriction(
15756                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)) {
15757                    continue;
15758                }
15759                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
15760                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
15761                if (user != 0 && newReceivers != null) {
15762                    // If this is not the primary user, we need to check for
15763                    // any receivers that should be filtered out.
15764                    for (int i=0; i<newReceivers.size(); i++) {
15765                        ResolveInfo ri = newReceivers.get(i);
15766                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
15767                            newReceivers.remove(i);
15768                            i--;
15769                        }
15770                    }
15771                }
15772                if (newReceivers != null && newReceivers.size() == 0) {
15773                    newReceivers = null;
15774                }
15775                if (receivers == null) {
15776                    receivers = newReceivers;
15777                } else if (newReceivers != null) {
15778                    // We need to concatenate the additional receivers
15779                    // found with what we have do far.  This would be easy,
15780                    // but we also need to de-dup any receivers that are
15781                    // singleUser.
15782                    if (!scannedFirstReceivers) {
15783                        // Collect any single user receivers we had already retrieved.
15784                        scannedFirstReceivers = true;
15785                        for (int i=0; i<receivers.size(); i++) {
15786                            ResolveInfo ri = receivers.get(i);
15787                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15788                                ComponentName cn = new ComponentName(
15789                                        ri.activityInfo.packageName, ri.activityInfo.name);
15790                                if (singleUserReceivers == null) {
15791                                    singleUserReceivers = new HashSet<ComponentName>();
15792                                }
15793                                singleUserReceivers.add(cn);
15794                            }
15795                        }
15796                    }
15797                    // Add the new results to the existing results, tracking
15798                    // and de-dupping single user receivers.
15799                    for (int i=0; i<newReceivers.size(); i++) {
15800                        ResolveInfo ri = newReceivers.get(i);
15801                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15802                            ComponentName cn = new ComponentName(
15803                                    ri.activityInfo.packageName, ri.activityInfo.name);
15804                            if (singleUserReceivers == null) {
15805                                singleUserReceivers = new HashSet<ComponentName>();
15806                            }
15807                            if (!singleUserReceivers.contains(cn)) {
15808                                singleUserReceivers.add(cn);
15809                                receivers.add(ri);
15810                            }
15811                        } else {
15812                            receivers.add(ri);
15813                        }
15814                    }
15815                }
15816            }
15817        } catch (RemoteException ex) {
15818            // pm is in same process, this will never happen.
15819        }
15820        return receivers;
15821    }
15822
15823    private final int broadcastIntentLocked(ProcessRecord callerApp,
15824            String callerPackage, Intent intent, String resolvedType,
15825            IIntentReceiver resultTo, int resultCode, String resultData,
15826            Bundle map, String requiredPermission, int appOp,
15827            boolean ordered, boolean sticky, int callingPid, int callingUid,
15828            int userId) {
15829        intent = new Intent(intent);
15830
15831        // By default broadcasts do not go to stopped apps.
15832        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
15833
15834        if (DEBUG_BROADCAST_LIGHT) Slog.v(
15835            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
15836            + " ordered=" + ordered + " userid=" + userId);
15837        if ((resultTo != null) && !ordered) {
15838            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
15839        }
15840
15841        userId = handleIncomingUser(callingPid, callingUid, userId,
15842                true, ALLOW_NON_FULL, "broadcast", callerPackage);
15843
15844        // Make sure that the user who is receiving this broadcast is running.
15845        // If not, we will just skip it. Make an exception for shutdown broadcasts
15846        // and upgrade steps.
15847
15848        if (userId != UserHandle.USER_ALL && !isUserRunningLocked(userId, false)) {
15849            if ((callingUid != Process.SYSTEM_UID
15850                    || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
15851                    && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
15852                Slog.w(TAG, "Skipping broadcast of " + intent
15853                        + ": user " + userId + " is stopped");
15854                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
15855            }
15856        }
15857
15858        /*
15859         * Prevent non-system code (defined here to be non-persistent
15860         * processes) from sending protected broadcasts.
15861         */
15862        int callingAppId = UserHandle.getAppId(callingUid);
15863        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
15864            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
15865            || callingAppId == Process.NFC_UID || callingUid == 0) {
15866            // Always okay.
15867        } else if (callerApp == null || !callerApp.persistent) {
15868            try {
15869                if (AppGlobals.getPackageManager().isProtectedBroadcast(
15870                        intent.getAction())) {
15871                    String msg = "Permission Denial: not allowed to send broadcast "
15872                            + intent.getAction() + " from pid="
15873                            + callingPid + ", uid=" + callingUid;
15874                    Slog.w(TAG, msg);
15875                    throw new SecurityException(msg);
15876                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
15877                    // Special case for compatibility: we don't want apps to send this,
15878                    // but historically it has not been protected and apps may be using it
15879                    // to poke their own app widget.  So, instead of making it protected,
15880                    // just limit it to the caller.
15881                    if (callerApp == null) {
15882                        String msg = "Permission Denial: not allowed to send broadcast "
15883                                + intent.getAction() + " from unknown caller.";
15884                        Slog.w(TAG, msg);
15885                        throw new SecurityException(msg);
15886                    } else if (intent.getComponent() != null) {
15887                        // They are good enough to send to an explicit component...  verify
15888                        // it is being sent to the calling app.
15889                        if (!intent.getComponent().getPackageName().equals(
15890                                callerApp.info.packageName)) {
15891                            String msg = "Permission Denial: not allowed to send broadcast "
15892                                    + intent.getAction() + " to "
15893                                    + intent.getComponent().getPackageName() + " from "
15894                                    + callerApp.info.packageName;
15895                            Slog.w(TAG, msg);
15896                            throw new SecurityException(msg);
15897                        }
15898                    } else {
15899                        // Limit broadcast to their own package.
15900                        intent.setPackage(callerApp.info.packageName);
15901                    }
15902                }
15903            } catch (RemoteException e) {
15904                Slog.w(TAG, "Remote exception", e);
15905                return ActivityManager.BROADCAST_SUCCESS;
15906            }
15907        }
15908
15909        final String action = intent.getAction();
15910        if (action != null) {
15911            switch (action) {
15912                case Intent.ACTION_UID_REMOVED:
15913                case Intent.ACTION_PACKAGE_REMOVED:
15914                case Intent.ACTION_PACKAGE_CHANGED:
15915                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
15916                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
15917                    // Handle special intents: if this broadcast is from the package
15918                    // manager about a package being removed, we need to remove all of
15919                    // its activities from the history stack.
15920                    if (checkComponentPermission(
15921                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
15922                            callingPid, callingUid, -1, true)
15923                            != PackageManager.PERMISSION_GRANTED) {
15924                        String msg = "Permission Denial: " + intent.getAction()
15925                                + " broadcast from " + callerPackage + " (pid=" + callingPid
15926                                + ", uid=" + callingUid + ")"
15927                                + " requires "
15928                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
15929                        Slog.w(TAG, msg);
15930                        throw new SecurityException(msg);
15931                    }
15932                    switch (action) {
15933                        case Intent.ACTION_UID_REMOVED:
15934                            final Bundle intentExtras = intent.getExtras();
15935                            final int uid = intentExtras != null
15936                                    ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
15937                            if (uid >= 0) {
15938                                BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
15939                                synchronized (bs) {
15940                                    bs.removeUidStatsLocked(uid);
15941                                }
15942                                mAppOpsService.uidRemoved(uid);
15943                            }
15944                            break;
15945                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
15946                            // If resources are unavailable just force stop all those packages
15947                            // and flush the attribute cache as well.
15948                            String list[] =
15949                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15950                            if (list != null && list.length > 0) {
15951                                for (int i = 0; i < list.length; i++) {
15952                                    forceStopPackageLocked(list[i], -1, false, true, true,
15953                                            false, false, userId, "storage unmount");
15954                                }
15955                                cleanupRecentTasksLocked(UserHandle.USER_ALL);
15956                                sendPackageBroadcastLocked(
15957                                        IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
15958                                        userId);
15959                            }
15960                            break;
15961                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
15962                            cleanupRecentTasksLocked(UserHandle.USER_ALL);
15963                            break;
15964                        case Intent.ACTION_PACKAGE_REMOVED:
15965                        case Intent.ACTION_PACKAGE_CHANGED:
15966                            Uri data = intent.getData();
15967                            String ssp;
15968                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
15969                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
15970                                boolean fullUninstall = removed &&
15971                                        !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
15972                                if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
15973                                    forceStopPackageLocked(ssp, UserHandle.getAppId(
15974                                            intent.getIntExtra(Intent.EXTRA_UID, -1)),
15975                                            false, true, true, false, fullUninstall, userId,
15976                                            removed ? "pkg removed" : "pkg changed");
15977                                }
15978                                if (removed) {
15979                                    sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
15980                                            new String[] {ssp}, userId);
15981                                    if (fullUninstall) {
15982                                        mAppOpsService.packageRemoved(
15983                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
15984
15985                                        // Remove all permissions granted from/to this package
15986                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
15987
15988                                        removeTasksByPackageNameLocked(ssp, userId);
15989                                    }
15990                                } else {
15991                                    removeTasksByRemovedPackageComponentsLocked(ssp, userId);
15992                                    if (userId == UserHandle.USER_OWNER) {
15993                                        mTaskPersister.addOtherDeviceTasksToRecentsLocked(ssp);
15994                                    }
15995                                }
15996                            }
15997                            break;
15998                    }
15999                    break;
16000                case Intent.ACTION_PACKAGE_ADDED:
16001                    // Special case for adding a package: by default turn on compatibility mode.
16002                    Uri data = intent.getData();
16003                    String ssp;
16004                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
16005                        final boolean replacing =
16006                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
16007                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
16008
16009                        if (replacing) {
16010                            removeTasksByRemovedPackageComponentsLocked(ssp, userId);
16011                        }
16012                        if (userId == UserHandle.USER_OWNER) {
16013                            mTaskPersister.addOtherDeviceTasksToRecentsLocked(ssp);
16014                        }
16015                    }
16016                    break;
16017                case Intent.ACTION_TIMEZONE_CHANGED:
16018                    // If this is the time zone changed action, queue up a message that will reset
16019                    // the timezone of all currently running processes. This message will get
16020                    // queued up before the broadcast happens.
16021                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
16022                    break;
16023                case Intent.ACTION_TIME_CHANGED:
16024                    // If the user set the time, let all running processes know.
16025                    final int is24Hour =
16026                            intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
16027                                    : 0;
16028                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
16029                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16030                    synchronized (stats) {
16031                        stats.noteCurrentTimeChangedLocked();
16032                    }
16033                    break;
16034                case Intent.ACTION_CLEAR_DNS_CACHE:
16035                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
16036                    break;
16037                case Proxy.PROXY_CHANGE_ACTION:
16038                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
16039                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
16040                    break;
16041            }
16042        }
16043
16044        // Add to the sticky list if requested.
16045        if (sticky) {
16046            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
16047                    callingPid, callingUid)
16048                    != PackageManager.PERMISSION_GRANTED) {
16049                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
16050                        + callingPid + ", uid=" + callingUid
16051                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
16052                Slog.w(TAG, msg);
16053                throw new SecurityException(msg);
16054            }
16055            if (requiredPermission != null) {
16056                Slog.w(TAG, "Can't broadcast sticky intent " + intent
16057                        + " and enforce permission " + requiredPermission);
16058                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
16059            }
16060            if (intent.getComponent() != null) {
16061                throw new SecurityException(
16062                        "Sticky broadcasts can't target a specific component");
16063            }
16064            // We use userId directly here, since the "all" target is maintained
16065            // as a separate set of sticky broadcasts.
16066            if (userId != UserHandle.USER_ALL) {
16067                // But first, if this is not a broadcast to all users, then
16068                // make sure it doesn't conflict with an existing broadcast to
16069                // all users.
16070                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
16071                        UserHandle.USER_ALL);
16072                if (stickies != null) {
16073                    ArrayList<Intent> list = stickies.get(intent.getAction());
16074                    if (list != null) {
16075                        int N = list.size();
16076                        int i;
16077                        for (i=0; i<N; i++) {
16078                            if (intent.filterEquals(list.get(i))) {
16079                                throw new IllegalArgumentException(
16080                                        "Sticky broadcast " + intent + " for user "
16081                                        + userId + " conflicts with existing global broadcast");
16082                            }
16083                        }
16084                    }
16085                }
16086            }
16087            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
16088            if (stickies == null) {
16089                stickies = new ArrayMap<String, ArrayList<Intent>>();
16090                mStickyBroadcasts.put(userId, stickies);
16091            }
16092            ArrayList<Intent> list = stickies.get(intent.getAction());
16093            if (list == null) {
16094                list = new ArrayList<Intent>();
16095                stickies.put(intent.getAction(), list);
16096            }
16097            int N = list.size();
16098            int i;
16099            for (i=0; i<N; i++) {
16100                if (intent.filterEquals(list.get(i))) {
16101                    // This sticky already exists, replace it.
16102                    list.set(i, new Intent(intent));
16103                    break;
16104                }
16105            }
16106            if (i >= N) {
16107                list.add(new Intent(intent));
16108            }
16109        }
16110
16111        int[] users;
16112        if (userId == UserHandle.USER_ALL) {
16113            // Caller wants broadcast to go to all started users.
16114            users = mStartedUserArray;
16115        } else {
16116            // Caller wants broadcast to go to one specific user.
16117            users = new int[] {userId};
16118        }
16119
16120        // Figure out who all will receive this broadcast.
16121        List receivers = null;
16122        List<BroadcastFilter> registeredReceivers = null;
16123        // Need to resolve the intent to interested receivers...
16124        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
16125                 == 0) {
16126            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
16127        }
16128        if (intent.getComponent() == null) {
16129            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
16130                // Query one target user at a time, excluding shell-restricted users
16131                UserManagerService ums = getUserManagerLocked();
16132                for (int i = 0; i < users.length; i++) {
16133                    if (ums.hasUserRestriction(
16134                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
16135                        continue;
16136                    }
16137                    List<BroadcastFilter> registeredReceiversForUser =
16138                            mReceiverResolver.queryIntent(intent,
16139                                    resolvedType, false, users[i]);
16140                    if (registeredReceivers == null) {
16141                        registeredReceivers = registeredReceiversForUser;
16142                    } else if (registeredReceiversForUser != null) {
16143                        registeredReceivers.addAll(registeredReceiversForUser);
16144                    }
16145                }
16146            } else {
16147                registeredReceivers = mReceiverResolver.queryIntent(intent,
16148                        resolvedType, false, userId);
16149            }
16150        }
16151
16152        final boolean replacePending =
16153                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
16154
16155        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
16156                + " replacePending=" + replacePending);
16157
16158        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
16159        if (!ordered && NR > 0) {
16160            // If we are not serializing this broadcast, then send the
16161            // registered receivers separately so they don't wait for the
16162            // components to be launched.
16163            final BroadcastQueue queue = broadcastQueueForIntent(intent);
16164            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
16165                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
16166                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
16167                    ordered, sticky, false, userId);
16168            if (DEBUG_BROADCAST) Slog.v(
16169                    TAG, "Enqueueing parallel broadcast " + r);
16170            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
16171            if (!replaced) {
16172                queue.enqueueParallelBroadcastLocked(r);
16173                queue.scheduleBroadcastsLocked();
16174            }
16175            registeredReceivers = null;
16176            NR = 0;
16177        }
16178
16179        // Merge into one list.
16180        int ir = 0;
16181        if (receivers != null) {
16182            // A special case for PACKAGE_ADDED: do not allow the package
16183            // being added to see this broadcast.  This prevents them from
16184            // using this as a back door to get run as soon as they are
16185            // installed.  Maybe in the future we want to have a special install
16186            // broadcast or such for apps, but we'd like to deliberately make
16187            // this decision.
16188            String skipPackages[] = null;
16189            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
16190                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
16191                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
16192                Uri data = intent.getData();
16193                if (data != null) {
16194                    String pkgName = data.getSchemeSpecificPart();
16195                    if (pkgName != null) {
16196                        skipPackages = new String[] { pkgName };
16197                    }
16198                }
16199            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
16200                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
16201            }
16202            if (skipPackages != null && (skipPackages.length > 0)) {
16203                for (String skipPackage : skipPackages) {
16204                    if (skipPackage != null) {
16205                        int NT = receivers.size();
16206                        for (int it=0; it<NT; it++) {
16207                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
16208                            if (curt.activityInfo.packageName.equals(skipPackage)) {
16209                                receivers.remove(it);
16210                                it--;
16211                                NT--;
16212                            }
16213                        }
16214                    }
16215                }
16216            }
16217
16218            int NT = receivers != null ? receivers.size() : 0;
16219            int it = 0;
16220            ResolveInfo curt = null;
16221            BroadcastFilter curr = null;
16222            while (it < NT && ir < NR) {
16223                if (curt == null) {
16224                    curt = (ResolveInfo)receivers.get(it);
16225                }
16226                if (curr == null) {
16227                    curr = registeredReceivers.get(ir);
16228                }
16229                if (curr.getPriority() >= curt.priority) {
16230                    // Insert this broadcast record into the final list.
16231                    receivers.add(it, curr);
16232                    ir++;
16233                    curr = null;
16234                    it++;
16235                    NT++;
16236                } else {
16237                    // Skip to the next ResolveInfo in the final list.
16238                    it++;
16239                    curt = null;
16240                }
16241            }
16242        }
16243        while (ir < NR) {
16244            if (receivers == null) {
16245                receivers = new ArrayList();
16246            }
16247            receivers.add(registeredReceivers.get(ir));
16248            ir++;
16249        }
16250
16251        if ((receivers != null && receivers.size() > 0)
16252                || resultTo != null) {
16253            BroadcastQueue queue = broadcastQueueForIntent(intent);
16254            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
16255                    callerPackage, callingPid, callingUid, resolvedType,
16256                    requiredPermission, appOp, receivers, resultTo, resultCode,
16257                    resultData, map, ordered, sticky, false, userId);
16258            if (DEBUG_BROADCAST) Slog.v(
16259                    TAG, "Enqueueing ordered broadcast " + r
16260                    + ": prev had " + queue.mOrderedBroadcasts.size());
16261            if (DEBUG_BROADCAST) {
16262                int seq = r.intent.getIntExtra("seq", -1);
16263                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
16264            }
16265            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
16266            if (!replaced) {
16267                queue.enqueueOrderedBroadcastLocked(r);
16268                queue.scheduleBroadcastsLocked();
16269            }
16270        }
16271
16272        return ActivityManager.BROADCAST_SUCCESS;
16273    }
16274
16275    final Intent verifyBroadcastLocked(Intent intent) {
16276        // Refuse possible leaked file descriptors
16277        if (intent != null && intent.hasFileDescriptors() == true) {
16278            throw new IllegalArgumentException("File descriptors passed in Intent");
16279        }
16280
16281        int flags = intent.getFlags();
16282
16283        if (!mProcessesReady) {
16284            // if the caller really truly claims to know what they're doing, go
16285            // ahead and allow the broadcast without launching any receivers
16286            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
16287                intent = new Intent(intent);
16288                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16289            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
16290                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
16291                        + " before boot completion");
16292                throw new IllegalStateException("Cannot broadcast before boot completed");
16293            }
16294        }
16295
16296        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
16297            throw new IllegalArgumentException(
16298                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
16299        }
16300
16301        return intent;
16302    }
16303
16304    public final int broadcastIntent(IApplicationThread caller,
16305            Intent intent, String resolvedType, IIntentReceiver resultTo,
16306            int resultCode, String resultData, Bundle map,
16307            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
16308        enforceNotIsolatedCaller("broadcastIntent");
16309        synchronized(this) {
16310            intent = verifyBroadcastLocked(intent);
16311
16312            final ProcessRecord callerApp = getRecordForAppLocked(caller);
16313            final int callingPid = Binder.getCallingPid();
16314            final int callingUid = Binder.getCallingUid();
16315            final long origId = Binder.clearCallingIdentity();
16316            int res = broadcastIntentLocked(callerApp,
16317                    callerApp != null ? callerApp.info.packageName : null,
16318                    intent, resolvedType, resultTo,
16319                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
16320                    callingPid, callingUid, userId);
16321            Binder.restoreCallingIdentity(origId);
16322            return res;
16323        }
16324    }
16325
16326    int broadcastIntentInPackage(String packageName, int uid,
16327            Intent intent, String resolvedType, IIntentReceiver resultTo,
16328            int resultCode, String resultData, Bundle map,
16329            String requiredPermission, boolean serialized, boolean sticky, int userId) {
16330        synchronized(this) {
16331            intent = verifyBroadcastLocked(intent);
16332
16333            final long origId = Binder.clearCallingIdentity();
16334            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
16335                    resultTo, resultCode, resultData, map, requiredPermission,
16336                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
16337            Binder.restoreCallingIdentity(origId);
16338            return res;
16339        }
16340    }
16341
16342    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
16343        // Refuse possible leaked file descriptors
16344        if (intent != null && intent.hasFileDescriptors() == true) {
16345            throw new IllegalArgumentException("File descriptors passed in Intent");
16346        }
16347
16348        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16349                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
16350
16351        synchronized(this) {
16352            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
16353                    != PackageManager.PERMISSION_GRANTED) {
16354                String msg = "Permission Denial: unbroadcastIntent() from pid="
16355                        + Binder.getCallingPid()
16356                        + ", uid=" + Binder.getCallingUid()
16357                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
16358                Slog.w(TAG, msg);
16359                throw new SecurityException(msg);
16360            }
16361            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
16362            if (stickies != null) {
16363                ArrayList<Intent> list = stickies.get(intent.getAction());
16364                if (list != null) {
16365                    int N = list.size();
16366                    int i;
16367                    for (i=0; i<N; i++) {
16368                        if (intent.filterEquals(list.get(i))) {
16369                            list.remove(i);
16370                            break;
16371                        }
16372                    }
16373                    if (list.size() <= 0) {
16374                        stickies.remove(intent.getAction());
16375                    }
16376                }
16377                if (stickies.size() <= 0) {
16378                    mStickyBroadcasts.remove(userId);
16379                }
16380            }
16381        }
16382    }
16383
16384    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
16385            String resultData, Bundle resultExtras, boolean resultAbort) {
16386        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
16387        if (r == null) {
16388            Slog.w(TAG, "finishReceiver called but not found on queue");
16389            return false;
16390        }
16391
16392        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
16393    }
16394
16395    void backgroundServicesFinishedLocked(int userId) {
16396        for (BroadcastQueue queue : mBroadcastQueues) {
16397            queue.backgroundServicesFinishedLocked(userId);
16398        }
16399    }
16400
16401    public void finishReceiver(IBinder who, int resultCode, String resultData,
16402            Bundle resultExtras, boolean resultAbort) {
16403        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
16404
16405        // Refuse possible leaked file descriptors
16406        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
16407            throw new IllegalArgumentException("File descriptors passed in Bundle");
16408        }
16409
16410        final long origId = Binder.clearCallingIdentity();
16411        try {
16412            boolean doNext = false;
16413            BroadcastRecord r;
16414
16415            synchronized(this) {
16416                r = broadcastRecordForReceiverLocked(who);
16417                if (r != null) {
16418                    doNext = r.queue.finishReceiverLocked(r, resultCode,
16419                        resultData, resultExtras, resultAbort, true);
16420                }
16421            }
16422
16423            if (doNext) {
16424                r.queue.processNextBroadcast(false);
16425            }
16426            trimApplications();
16427        } finally {
16428            Binder.restoreCallingIdentity(origId);
16429        }
16430    }
16431
16432    // =========================================================
16433    // INSTRUMENTATION
16434    // =========================================================
16435
16436    public boolean startInstrumentation(ComponentName className,
16437            String profileFile, int flags, Bundle arguments,
16438            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
16439            int userId, String abiOverride) {
16440        enforceNotIsolatedCaller("startInstrumentation");
16441        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16442                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
16443        // Refuse possible leaked file descriptors
16444        if (arguments != null && arguments.hasFileDescriptors()) {
16445            throw new IllegalArgumentException("File descriptors passed in Bundle");
16446        }
16447
16448        synchronized(this) {
16449            InstrumentationInfo ii = null;
16450            ApplicationInfo ai = null;
16451            try {
16452                ii = mContext.getPackageManager().getInstrumentationInfo(
16453                    className, STOCK_PM_FLAGS);
16454                ai = AppGlobals.getPackageManager().getApplicationInfo(
16455                        ii.targetPackage, STOCK_PM_FLAGS, userId);
16456            } catch (PackageManager.NameNotFoundException e) {
16457            } catch (RemoteException e) {
16458            }
16459            if (ii == null) {
16460                reportStartInstrumentationFailure(watcher, className,
16461                        "Unable to find instrumentation info for: " + className);
16462                return false;
16463            }
16464            if (ai == null) {
16465                reportStartInstrumentationFailure(watcher, className,
16466                        "Unable to find instrumentation target package: " + ii.targetPackage);
16467                return false;
16468            }
16469
16470            int match = mContext.getPackageManager().checkSignatures(
16471                    ii.targetPackage, ii.packageName);
16472            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
16473                String msg = "Permission Denial: starting instrumentation "
16474                        + className + " from pid="
16475                        + Binder.getCallingPid()
16476                        + ", uid=" + Binder.getCallingPid()
16477                        + " not allowed because package " + ii.packageName
16478                        + " does not have a signature matching the target "
16479                        + ii.targetPackage;
16480                reportStartInstrumentationFailure(watcher, className, msg);
16481                throw new SecurityException(msg);
16482            }
16483
16484            final long origId = Binder.clearCallingIdentity();
16485            // Instrumentation can kill and relaunch even persistent processes
16486            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
16487                    "start instr");
16488            ProcessRecord app = addAppLocked(ai, false, abiOverride);
16489            app.instrumentationClass = className;
16490            app.instrumentationInfo = ai;
16491            app.instrumentationProfileFile = profileFile;
16492            app.instrumentationArguments = arguments;
16493            app.instrumentationWatcher = watcher;
16494            app.instrumentationUiAutomationConnection = uiAutomationConnection;
16495            app.instrumentationResultClass = className;
16496            Binder.restoreCallingIdentity(origId);
16497        }
16498
16499        return true;
16500    }
16501
16502    /**
16503     * Report errors that occur while attempting to start Instrumentation.  Always writes the
16504     * error to the logs, but if somebody is watching, send the report there too.  This enables
16505     * the "am" command to report errors with more information.
16506     *
16507     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
16508     * @param cn The component name of the instrumentation.
16509     * @param report The error report.
16510     */
16511    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
16512            ComponentName cn, String report) {
16513        Slog.w(TAG, report);
16514        try {
16515            if (watcher != null) {
16516                Bundle results = new Bundle();
16517                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
16518                results.putString("Error", report);
16519                watcher.instrumentationStatus(cn, -1, results);
16520            }
16521        } catch (RemoteException e) {
16522            Slog.w(TAG, e);
16523        }
16524    }
16525
16526    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
16527        if (app.instrumentationWatcher != null) {
16528            try {
16529                // NOTE:  IInstrumentationWatcher *must* be oneway here
16530                app.instrumentationWatcher.instrumentationFinished(
16531                    app.instrumentationClass,
16532                    resultCode,
16533                    results);
16534            } catch (RemoteException e) {
16535            }
16536        }
16537        if (app.instrumentationUiAutomationConnection != null) {
16538            try {
16539                app.instrumentationUiAutomationConnection.shutdown();
16540            } catch (RemoteException re) {
16541                /* ignore */
16542            }
16543            // Only a UiAutomation can set this flag and now that
16544            // it is finished we make sure it is reset to its default.
16545            mUserIsMonkey = false;
16546        }
16547        app.instrumentationWatcher = null;
16548        app.instrumentationUiAutomationConnection = null;
16549        app.instrumentationClass = null;
16550        app.instrumentationInfo = null;
16551        app.instrumentationProfileFile = null;
16552        app.instrumentationArguments = null;
16553
16554        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
16555                "finished inst");
16556    }
16557
16558    public void finishInstrumentation(IApplicationThread target,
16559            int resultCode, Bundle results) {
16560        int userId = UserHandle.getCallingUserId();
16561        // Refuse possible leaked file descriptors
16562        if (results != null && results.hasFileDescriptors()) {
16563            throw new IllegalArgumentException("File descriptors passed in Intent");
16564        }
16565
16566        synchronized(this) {
16567            ProcessRecord app = getRecordForAppLocked(target);
16568            if (app == null) {
16569                Slog.w(TAG, "finishInstrumentation: no app for " + target);
16570                return;
16571            }
16572            final long origId = Binder.clearCallingIdentity();
16573            finishInstrumentationLocked(app, resultCode, results);
16574            Binder.restoreCallingIdentity(origId);
16575        }
16576    }
16577
16578    // =========================================================
16579    // CONFIGURATION
16580    // =========================================================
16581
16582    public ConfigurationInfo getDeviceConfigurationInfo() {
16583        ConfigurationInfo config = new ConfigurationInfo();
16584        synchronized (this) {
16585            config.reqTouchScreen = mConfiguration.touchscreen;
16586            config.reqKeyboardType = mConfiguration.keyboard;
16587            config.reqNavigation = mConfiguration.navigation;
16588            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
16589                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
16590                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
16591            }
16592            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
16593                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
16594                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
16595            }
16596            config.reqGlEsVersion = GL_ES_VERSION;
16597        }
16598        return config;
16599    }
16600
16601    ActivityStack getFocusedStack() {
16602        return mStackSupervisor.getFocusedStack();
16603    }
16604
16605    public Configuration getConfiguration() {
16606        Configuration ci;
16607        synchronized(this) {
16608            ci = new Configuration(mConfiguration);
16609            ci.userSetLocale = false;
16610        }
16611        return ci;
16612    }
16613
16614    public void updatePersistentConfiguration(Configuration values) {
16615        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16616                "updateConfiguration()");
16617        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
16618                "updateConfiguration()");
16619        if (values == null) {
16620            throw new NullPointerException("Configuration must not be null");
16621        }
16622
16623        synchronized(this) {
16624            final long origId = Binder.clearCallingIdentity();
16625            updateConfigurationLocked(values, null, true, false);
16626            Binder.restoreCallingIdentity(origId);
16627        }
16628    }
16629
16630    public void updateConfiguration(Configuration values) {
16631        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16632                "updateConfiguration()");
16633
16634        synchronized(this) {
16635            if (values == null && mWindowManager != null) {
16636                // sentinel: fetch the current configuration from the window manager
16637                values = mWindowManager.computeNewConfiguration();
16638            }
16639
16640            if (mWindowManager != null) {
16641                mProcessList.applyDisplaySize(mWindowManager);
16642            }
16643
16644            final long origId = Binder.clearCallingIdentity();
16645            if (values != null) {
16646                Settings.System.clearConfiguration(values);
16647            }
16648            updateConfigurationLocked(values, null, false, false);
16649            Binder.restoreCallingIdentity(origId);
16650        }
16651    }
16652
16653    /**
16654     * Do either or both things: (1) change the current configuration, and (2)
16655     * make sure the given activity is running with the (now) current
16656     * configuration.  Returns true if the activity has been left running, or
16657     * false if <var>starting</var> is being destroyed to match the new
16658     * configuration.
16659     * @param persistent TODO
16660     */
16661    boolean updateConfigurationLocked(Configuration values,
16662            ActivityRecord starting, boolean persistent, boolean initLocale) {
16663        int changes = 0;
16664
16665        if (values != null) {
16666            Configuration newConfig = new Configuration(mConfiguration);
16667            changes = newConfig.updateFrom(values);
16668            if (changes != 0) {
16669                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
16670                    Slog.i(TAG, "Updating configuration to: " + values);
16671                }
16672
16673                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
16674
16675                if (values.locale != null && !initLocale) {
16676                    saveLocaleLocked(values.locale,
16677                                     !values.locale.equals(mConfiguration.locale),
16678                                     values.userSetLocale);
16679                }
16680
16681                mConfigurationSeq++;
16682                if (mConfigurationSeq <= 0) {
16683                    mConfigurationSeq = 1;
16684                }
16685                newConfig.seq = mConfigurationSeq;
16686                mConfiguration = newConfig;
16687                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
16688                mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId);
16689                //mUsageStatsService.noteStartConfig(newConfig);
16690
16691                final Configuration configCopy = new Configuration(mConfiguration);
16692
16693                // TODO: If our config changes, should we auto dismiss any currently
16694                // showing dialogs?
16695                mShowDialogs = shouldShowDialogs(newConfig);
16696
16697                AttributeCache ac = AttributeCache.instance();
16698                if (ac != null) {
16699                    ac.updateConfiguration(configCopy);
16700                }
16701
16702                // Make sure all resources in our process are updated
16703                // right now, so that anyone who is going to retrieve
16704                // resource values after we return will be sure to get
16705                // the new ones.  This is especially important during
16706                // boot, where the first config change needs to guarantee
16707                // all resources have that config before following boot
16708                // code is executed.
16709                mSystemThread.applyConfigurationToResources(configCopy);
16710
16711                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
16712                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
16713                    msg.obj = new Configuration(configCopy);
16714                    mHandler.sendMessage(msg);
16715                }
16716
16717                for (int i=mLruProcesses.size()-1; i>=0; i--) {
16718                    ProcessRecord app = mLruProcesses.get(i);
16719                    try {
16720                        if (app.thread != null) {
16721                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
16722                                    + app.processName + " new config " + mConfiguration);
16723                            app.thread.scheduleConfigurationChanged(configCopy);
16724                        }
16725                    } catch (Exception e) {
16726                    }
16727                }
16728                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
16729                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16730                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
16731                        | Intent.FLAG_RECEIVER_FOREGROUND);
16732                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
16733                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
16734                        Process.SYSTEM_UID, UserHandle.USER_ALL);
16735                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
16736                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
16737                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16738                    broadcastIntentLocked(null, null, intent,
16739                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16740                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16741                }
16742            }
16743        }
16744
16745        boolean kept = true;
16746        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
16747        // mainStack is null during startup.
16748        if (mainStack != null) {
16749            if (changes != 0 && starting == null) {
16750                // If the configuration changed, and the caller is not already
16751                // in the process of starting an activity, then find the top
16752                // activity to check if its configuration needs to change.
16753                starting = mainStack.topRunningActivityLocked(null);
16754            }
16755
16756            if (starting != null) {
16757                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
16758                // And we need to make sure at this point that all other activities
16759                // are made visible with the correct configuration.
16760                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
16761            }
16762        }
16763
16764        if (values != null && mWindowManager != null) {
16765            mWindowManager.setNewConfiguration(mConfiguration);
16766        }
16767
16768        return kept;
16769    }
16770
16771    /**
16772     * Decide based on the configuration whether we should shouw the ANR,
16773     * crash, etc dialogs.  The idea is that if there is no affordnace to
16774     * press the on-screen buttons, we shouldn't show the dialog.
16775     *
16776     * A thought: SystemUI might also want to get told about this, the Power
16777     * dialog / global actions also might want different behaviors.
16778     */
16779    private static final boolean shouldShowDialogs(Configuration config) {
16780        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
16781                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
16782    }
16783
16784    /**
16785     * Save the locale.  You must be inside a synchronized (this) block.
16786     */
16787    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
16788        if(isDiff) {
16789            SystemProperties.set("user.language", l.getLanguage());
16790            SystemProperties.set("user.region", l.getCountry());
16791        }
16792
16793        if(isPersist) {
16794            SystemProperties.set("persist.sys.language", l.getLanguage());
16795            SystemProperties.set("persist.sys.country", l.getCountry());
16796            SystemProperties.set("persist.sys.localevar", l.getVariant());
16797
16798            mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG, l));
16799        }
16800    }
16801
16802    @Override
16803    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
16804        synchronized (this) {
16805            ActivityRecord srec = ActivityRecord.forToken(token);
16806            if (srec.task != null && srec.task.stack != null) {
16807                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
16808            }
16809        }
16810        return false;
16811    }
16812
16813    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
16814            Intent resultData) {
16815
16816        synchronized (this) {
16817            final ActivityStack stack = ActivityRecord.getStackLocked(token);
16818            if (stack != null) {
16819                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
16820            }
16821            return false;
16822        }
16823    }
16824
16825    public int getLaunchedFromUid(IBinder activityToken) {
16826        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16827        if (srec == null) {
16828            return -1;
16829        }
16830        return srec.launchedFromUid;
16831    }
16832
16833    public String getLaunchedFromPackage(IBinder activityToken) {
16834        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16835        if (srec == null) {
16836            return null;
16837        }
16838        return srec.launchedFromPackage;
16839    }
16840
16841    // =========================================================
16842    // LIFETIME MANAGEMENT
16843    // =========================================================
16844
16845    // Returns which broadcast queue the app is the current [or imminent] receiver
16846    // on, or 'null' if the app is not an active broadcast recipient.
16847    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
16848        BroadcastRecord r = app.curReceiver;
16849        if (r != null) {
16850            return r.queue;
16851        }
16852
16853        // It's not the current receiver, but it might be starting up to become one
16854        synchronized (this) {
16855            for (BroadcastQueue queue : mBroadcastQueues) {
16856                r = queue.mPendingBroadcast;
16857                if (r != null && r.curApp == app) {
16858                    // found it; report which queue it's in
16859                    return queue;
16860                }
16861            }
16862        }
16863
16864        return null;
16865    }
16866
16867    Association startAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
16868            ComponentName targetComponent, String targetProcess) {
16869        if (!mTrackingAssociations) {
16870            return null;
16871        }
16872        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
16873                = mAssociations.get(targetUid);
16874        if (components == null) {
16875            components = new ArrayMap<>();
16876            mAssociations.put(targetUid, components);
16877        }
16878        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
16879        if (sourceUids == null) {
16880            sourceUids = new SparseArray<>();
16881            components.put(targetComponent, sourceUids);
16882        }
16883        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
16884        if (sourceProcesses == null) {
16885            sourceProcesses = new ArrayMap<>();
16886            sourceUids.put(sourceUid, sourceProcesses);
16887        }
16888        Association ass = sourceProcesses.get(sourceProcess);
16889        if (ass == null) {
16890            ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
16891                    targetProcess);
16892            sourceProcesses.put(sourceProcess, ass);
16893        }
16894        ass.mCount++;
16895        ass.mNesting++;
16896        if (ass.mNesting == 1) {
16897            ass.mStartTime = SystemClock.uptimeMillis();
16898        }
16899        return ass;
16900    }
16901
16902    void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
16903            ComponentName targetComponent) {
16904        if (!mTrackingAssociations) {
16905            return;
16906        }
16907        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
16908                = mAssociations.get(targetUid);
16909        if (components == null) {
16910            return;
16911        }
16912        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
16913        if (sourceUids == null) {
16914            return;
16915        }
16916        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
16917        if (sourceProcesses == null) {
16918            return;
16919        }
16920        Association ass = sourceProcesses.get(sourceProcess);
16921        if (ass == null || ass.mNesting <= 0) {
16922            return;
16923        }
16924        ass.mNesting--;
16925        if (ass.mNesting == 0) {
16926            ass.mTime += SystemClock.uptimeMillis() - ass.mStartTime;
16927        }
16928    }
16929
16930    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
16931            boolean doingAll, long now) {
16932        if (mAdjSeq == app.adjSeq) {
16933            // This adjustment has already been computed.
16934            return app.curRawAdj;
16935        }
16936
16937        if (app.thread == null) {
16938            app.adjSeq = mAdjSeq;
16939            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16940            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16941            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
16942        }
16943
16944        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
16945        app.adjSource = null;
16946        app.adjTarget = null;
16947        app.empty = false;
16948        app.cached = false;
16949
16950        final int activitiesSize = app.activities.size();
16951
16952        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16953            // The max adjustment doesn't allow this app to be anything
16954            // below foreground, so it is not worth doing work for it.
16955            app.adjType = "fixed";
16956            app.adjSeq = mAdjSeq;
16957            app.curRawAdj = app.maxAdj;
16958            app.foregroundActivities = false;
16959            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
16960            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
16961            // System processes can do UI, and when they do we want to have
16962            // them trim their memory after the user leaves the UI.  To
16963            // facilitate this, here we need to determine whether or not it
16964            // is currently showing UI.
16965            app.systemNoUi = true;
16966            if (app == TOP_APP) {
16967                app.systemNoUi = false;
16968            } else if (activitiesSize > 0) {
16969                for (int j = 0; j < activitiesSize; j++) {
16970                    final ActivityRecord r = app.activities.get(j);
16971                    if (r.visible) {
16972                        app.systemNoUi = false;
16973                    }
16974                }
16975            }
16976            if (!app.systemNoUi) {
16977                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
16978            }
16979            return (app.curAdj=app.maxAdj);
16980        }
16981
16982        app.systemNoUi = false;
16983
16984        // Determine the importance of the process, starting with most
16985        // important to least, and assign an appropriate OOM adjustment.
16986        int adj;
16987        int schedGroup;
16988        int procState;
16989        boolean foregroundActivities = false;
16990        BroadcastQueue queue;
16991        if (app == TOP_APP) {
16992            // The last app on the list is the foreground app.
16993            adj = ProcessList.FOREGROUND_APP_ADJ;
16994            schedGroup = Process.THREAD_GROUP_DEFAULT;
16995            app.adjType = "top-activity";
16996            foregroundActivities = true;
16997            procState = ActivityManager.PROCESS_STATE_TOP;
16998        } else if (app.instrumentationClass != null) {
16999            // Don't want to kill running instrumentation.
17000            adj = ProcessList.FOREGROUND_APP_ADJ;
17001            schedGroup = Process.THREAD_GROUP_DEFAULT;
17002            app.adjType = "instrumentation";
17003            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17004        } else if ((queue = isReceivingBroadcast(app)) != null) {
17005            // An app that is currently receiving a broadcast also
17006            // counts as being in the foreground for OOM killer purposes.
17007            // It's placed in a sched group based on the nature of the
17008            // broadcast as reflected by which queue it's active in.
17009            adj = ProcessList.FOREGROUND_APP_ADJ;
17010            schedGroup = (queue == mFgBroadcastQueue)
17011                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
17012            app.adjType = "broadcast";
17013            procState = ActivityManager.PROCESS_STATE_RECEIVER;
17014        } else if (app.executingServices.size() > 0) {
17015            // An app that is currently executing a service callback also
17016            // counts as being in the foreground.
17017            adj = ProcessList.FOREGROUND_APP_ADJ;
17018            schedGroup = app.execServicesFg ?
17019                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
17020            app.adjType = "exec-service";
17021            procState = ActivityManager.PROCESS_STATE_SERVICE;
17022            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
17023        } else {
17024            // As far as we know the process is empty.  We may change our mind later.
17025            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17026            // At this point we don't actually know the adjustment.  Use the cached adj
17027            // value that the caller wants us to.
17028            adj = cachedAdj;
17029            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17030            app.cached = true;
17031            app.empty = true;
17032            app.adjType = "cch-empty";
17033        }
17034
17035        // Examine all activities if not already foreground.
17036        if (!foregroundActivities && activitiesSize > 0) {
17037            for (int j = 0; j < activitiesSize; j++) {
17038                final ActivityRecord r = app.activities.get(j);
17039                if (r.app != app) {
17040                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
17041                            + app + "?!?");
17042                    continue;
17043                }
17044                if (r.visible) {
17045                    // App has a visible activity; only upgrade adjustment.
17046                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
17047                        adj = ProcessList.VISIBLE_APP_ADJ;
17048                        app.adjType = "visible";
17049                    }
17050                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
17051                        procState = ActivityManager.PROCESS_STATE_TOP;
17052                    }
17053                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17054                    app.cached = false;
17055                    app.empty = false;
17056                    foregroundActivities = true;
17057                    break;
17058                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
17059                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17060                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17061                        app.adjType = "pausing";
17062                    }
17063                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
17064                        procState = ActivityManager.PROCESS_STATE_TOP;
17065                    }
17066                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17067                    app.cached = false;
17068                    app.empty = false;
17069                    foregroundActivities = true;
17070                } else if (r.state == ActivityState.STOPPING) {
17071                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17072                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17073                        app.adjType = "stopping";
17074                    }
17075                    // For the process state, we will at this point consider the
17076                    // process to be cached.  It will be cached either as an activity
17077                    // or empty depending on whether the activity is finishing.  We do
17078                    // this so that we can treat the process as cached for purposes of
17079                    // memory trimming (determing current memory level, trim command to
17080                    // send to process) since there can be an arbitrary number of stopping
17081                    // processes and they should soon all go into the cached state.
17082                    if (!r.finishing) {
17083                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
17084                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
17085                        }
17086                    }
17087                    app.cached = false;
17088                    app.empty = false;
17089                    foregroundActivities = true;
17090                } else {
17091                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
17092                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
17093                        app.adjType = "cch-act";
17094                    }
17095                }
17096            }
17097        }
17098
17099        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17100            if (app.foregroundServices) {
17101                // The user is aware of this app, so make it visible.
17102                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17103                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17104                app.cached = false;
17105                app.adjType = "fg-service";
17106                schedGroup = Process.THREAD_GROUP_DEFAULT;
17107            } else if (app.forcingToForeground != null) {
17108                // The user is aware of this app, so make it visible.
17109                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17110                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17111                app.cached = false;
17112                app.adjType = "force-fg";
17113                app.adjSource = app.forcingToForeground;
17114                schedGroup = Process.THREAD_GROUP_DEFAULT;
17115            }
17116        }
17117
17118        if (app == mHeavyWeightProcess) {
17119            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
17120                // We don't want to kill the current heavy-weight process.
17121                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
17122                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17123                app.cached = false;
17124                app.adjType = "heavy";
17125            }
17126            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
17127                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
17128            }
17129        }
17130
17131        if (app == mHomeProcess) {
17132            if (adj > ProcessList.HOME_APP_ADJ) {
17133                // This process is hosting what we currently consider to be the
17134                // home app, so we don't want to let it go into the background.
17135                adj = ProcessList.HOME_APP_ADJ;
17136                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17137                app.cached = false;
17138                app.adjType = "home";
17139            }
17140            if (procState > ActivityManager.PROCESS_STATE_HOME) {
17141                procState = ActivityManager.PROCESS_STATE_HOME;
17142            }
17143        }
17144
17145        if (app == mPreviousProcess && app.activities.size() > 0) {
17146            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
17147                // This was the previous process that showed UI to the user.
17148                // We want to try to keep it around more aggressively, to give
17149                // a good experience around switching between two apps.
17150                adj = ProcessList.PREVIOUS_APP_ADJ;
17151                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17152                app.cached = false;
17153                app.adjType = "previous";
17154            }
17155            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
17156                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
17157            }
17158        }
17159
17160        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
17161                + " reason=" + app.adjType);
17162
17163        // By default, we use the computed adjustment.  It may be changed if
17164        // there are applications dependent on our services or providers, but
17165        // this gives us a baseline and makes sure we don't get into an
17166        // infinite recursion.
17167        app.adjSeq = mAdjSeq;
17168        app.curRawAdj = adj;
17169        app.hasStartedServices = false;
17170
17171        if (mBackupTarget != null && app == mBackupTarget.app) {
17172            // If possible we want to avoid killing apps while they're being backed up
17173            if (adj > ProcessList.BACKUP_APP_ADJ) {
17174                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
17175                adj = ProcessList.BACKUP_APP_ADJ;
17176                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
17177                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
17178                }
17179                app.adjType = "backup";
17180                app.cached = false;
17181            }
17182            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
17183                procState = ActivityManager.PROCESS_STATE_BACKUP;
17184            }
17185        }
17186
17187        boolean mayBeTop = false;
17188
17189        for (int is = app.services.size()-1;
17190                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17191                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17192                        || procState > ActivityManager.PROCESS_STATE_TOP);
17193                is--) {
17194            ServiceRecord s = app.services.valueAt(is);
17195            if (s.startRequested) {
17196                app.hasStartedServices = true;
17197                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
17198                    procState = ActivityManager.PROCESS_STATE_SERVICE;
17199                }
17200                if (app.hasShownUi && app != mHomeProcess) {
17201                    // If this process has shown some UI, let it immediately
17202                    // go to the LRU list because it may be pretty heavy with
17203                    // UI stuff.  We'll tag it with a label just to help
17204                    // debug and understand what is going on.
17205                    if (adj > ProcessList.SERVICE_ADJ) {
17206                        app.adjType = "cch-started-ui-services";
17207                    }
17208                } else {
17209                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
17210                        // This service has seen some activity within
17211                        // recent memory, so we will keep its process ahead
17212                        // of the background processes.
17213                        if (adj > ProcessList.SERVICE_ADJ) {
17214                            adj = ProcessList.SERVICE_ADJ;
17215                            app.adjType = "started-services";
17216                            app.cached = false;
17217                        }
17218                    }
17219                    // If we have let the service slide into the background
17220                    // state, still have some text describing what it is doing
17221                    // even though the service no longer has an impact.
17222                    if (adj > ProcessList.SERVICE_ADJ) {
17223                        app.adjType = "cch-started-services";
17224                    }
17225                }
17226            }
17227            for (int conni = s.connections.size()-1;
17228                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17229                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17230                            || procState > ActivityManager.PROCESS_STATE_TOP);
17231                    conni--) {
17232                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
17233                for (int i = 0;
17234                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
17235                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17236                                || procState > ActivityManager.PROCESS_STATE_TOP);
17237                        i++) {
17238                    // XXX should compute this based on the max of
17239                    // all connected clients.
17240                    ConnectionRecord cr = clist.get(i);
17241                    if (cr.binding.client == app) {
17242                        // Binding to ourself is not interesting.
17243                        continue;
17244                    }
17245                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
17246                        ProcessRecord client = cr.binding.client;
17247                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
17248                                TOP_APP, doingAll, now);
17249                        int clientProcState = client.curProcState;
17250                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
17251                            // If the other app is cached for any reason, for purposes here
17252                            // we are going to consider it empty.  The specific cached state
17253                            // doesn't propagate except under certain conditions.
17254                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17255                        }
17256                        String adjType = null;
17257                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
17258                            // Not doing bind OOM management, so treat
17259                            // this guy more like a started service.
17260                            if (app.hasShownUi && app != mHomeProcess) {
17261                                // If this process has shown some UI, let it immediately
17262                                // go to the LRU list because it may be pretty heavy with
17263                                // UI stuff.  We'll tag it with a label just to help
17264                                // debug and understand what is going on.
17265                                if (adj > clientAdj) {
17266                                    adjType = "cch-bound-ui-services";
17267                                }
17268                                app.cached = false;
17269                                clientAdj = adj;
17270                                clientProcState = procState;
17271                            } else {
17272                                if (now >= (s.lastActivity
17273                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
17274                                    // This service has not seen activity within
17275                                    // recent memory, so allow it to drop to the
17276                                    // LRU list if there is no other reason to keep
17277                                    // it around.  We'll also tag it with a label just
17278                                    // to help debug and undertand what is going on.
17279                                    if (adj > clientAdj) {
17280                                        adjType = "cch-bound-services";
17281                                    }
17282                                    clientAdj = adj;
17283                                }
17284                            }
17285                        }
17286                        if (adj > clientAdj) {
17287                            // If this process has recently shown UI, and
17288                            // the process that is binding to it is less
17289                            // important than being visible, then we don't
17290                            // care about the binding as much as we care
17291                            // about letting this process get into the LRU
17292                            // list to be killed and restarted if needed for
17293                            // memory.
17294                            if (app.hasShownUi && app != mHomeProcess
17295                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17296                                adjType = "cch-bound-ui-services";
17297                            } else {
17298                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
17299                                        |Context.BIND_IMPORTANT)) != 0) {
17300                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
17301                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
17302                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
17303                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
17304                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17305                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17306                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
17307                                    adj = clientAdj;
17308                                } else {
17309                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
17310                                        adj = ProcessList.VISIBLE_APP_ADJ;
17311                                    }
17312                                }
17313                                if (!client.cached) {
17314                                    app.cached = false;
17315                                }
17316                                adjType = "service";
17317                            }
17318                        }
17319                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
17320                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
17321                                schedGroup = Process.THREAD_GROUP_DEFAULT;
17322                            }
17323                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
17324                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
17325                                    // Special handling of clients who are in the top state.
17326                                    // We *may* want to consider this process to be in the
17327                                    // top state as well, but only if there is not another
17328                                    // reason for it to be running.  Being on the top is a
17329                                    // special state, meaning you are specifically running
17330                                    // for the current top app.  If the process is already
17331                                    // running in the background for some other reason, it
17332                                    // is more important to continue considering it to be
17333                                    // in the background state.
17334                                    mayBeTop = true;
17335                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17336                                } else {
17337                                    // Special handling for above-top states (persistent
17338                                    // processes).  These should not bring the current process
17339                                    // into the top state, since they are not on top.  Instead
17340                                    // give them the best state after that.
17341                                    clientProcState =
17342                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17343                                }
17344                            }
17345                        } else {
17346                            if (clientProcState <
17347                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
17348                                clientProcState =
17349                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
17350                            }
17351                        }
17352                        if (procState > clientProcState) {
17353                            procState = clientProcState;
17354                        }
17355                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17356                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
17357                            app.pendingUiClean = true;
17358                        }
17359                        if (adjType != null) {
17360                            app.adjType = adjType;
17361                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17362                                    .REASON_SERVICE_IN_USE;
17363                            app.adjSource = cr.binding.client;
17364                            app.adjSourceProcState = clientProcState;
17365                            app.adjTarget = s.name;
17366                        }
17367                    }
17368                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
17369                        app.treatLikeActivity = true;
17370                    }
17371                    final ActivityRecord a = cr.activity;
17372                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
17373                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
17374                                (a.visible || a.state == ActivityState.RESUMED
17375                                 || a.state == ActivityState.PAUSING)) {
17376                            adj = ProcessList.FOREGROUND_APP_ADJ;
17377                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
17378                                schedGroup = Process.THREAD_GROUP_DEFAULT;
17379                            }
17380                            app.cached = false;
17381                            app.adjType = "service";
17382                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17383                                    .REASON_SERVICE_IN_USE;
17384                            app.adjSource = a;
17385                            app.adjSourceProcState = procState;
17386                            app.adjTarget = s.name;
17387                        }
17388                    }
17389                }
17390            }
17391        }
17392
17393        for (int provi = app.pubProviders.size()-1;
17394                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17395                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17396                        || procState > ActivityManager.PROCESS_STATE_TOP);
17397                provi--) {
17398            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
17399            for (int i = cpr.connections.size()-1;
17400                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17401                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17402                            || procState > ActivityManager.PROCESS_STATE_TOP);
17403                    i--) {
17404                ContentProviderConnection conn = cpr.connections.get(i);
17405                ProcessRecord client = conn.client;
17406                if (client == app) {
17407                    // Being our own client is not interesting.
17408                    continue;
17409                }
17410                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
17411                int clientProcState = client.curProcState;
17412                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
17413                    // If the other app is cached for any reason, for purposes here
17414                    // we are going to consider it empty.
17415                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17416                }
17417                if (adj > clientAdj) {
17418                    if (app.hasShownUi && app != mHomeProcess
17419                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17420                        app.adjType = "cch-ui-provider";
17421                    } else {
17422                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
17423                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
17424                        app.adjType = "provider";
17425                    }
17426                    app.cached &= client.cached;
17427                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17428                            .REASON_PROVIDER_IN_USE;
17429                    app.adjSource = client;
17430                    app.adjSourceProcState = clientProcState;
17431                    app.adjTarget = cpr.name;
17432                }
17433                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
17434                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
17435                        // Special handling of clients who are in the top state.
17436                        // We *may* want to consider this process to be in the
17437                        // top state as well, but only if there is not another
17438                        // reason for it to be running.  Being on the top is a
17439                        // special state, meaning you are specifically running
17440                        // for the current top app.  If the process is already
17441                        // running in the background for some other reason, it
17442                        // is more important to continue considering it to be
17443                        // in the background state.
17444                        mayBeTop = true;
17445                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17446                    } else {
17447                        // Special handling for above-top states (persistent
17448                        // processes).  These should not bring the current process
17449                        // into the top state, since they are not on top.  Instead
17450                        // give them the best state after that.
17451                        clientProcState =
17452                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17453                    }
17454                }
17455                if (procState > clientProcState) {
17456                    procState = clientProcState;
17457                }
17458                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
17459                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17460                }
17461            }
17462            // If the provider has external (non-framework) process
17463            // dependencies, ensure that its adjustment is at least
17464            // FOREGROUND_APP_ADJ.
17465            if (cpr.hasExternalProcessHandles()) {
17466                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
17467                    adj = ProcessList.FOREGROUND_APP_ADJ;
17468                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17469                    app.cached = false;
17470                    app.adjType = "provider";
17471                    app.adjTarget = cpr.name;
17472                }
17473                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
17474                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17475                }
17476            }
17477        }
17478
17479        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
17480            // A client of one of our services or providers is in the top state.  We
17481            // *may* want to be in the top state, but not if we are already running in
17482            // the background for some other reason.  For the decision here, we are going
17483            // to pick out a few specific states that we want to remain in when a client
17484            // is top (states that tend to be longer-term) and otherwise allow it to go
17485            // to the top state.
17486            switch (procState) {
17487                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
17488                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
17489                case ActivityManager.PROCESS_STATE_SERVICE:
17490                    // These all are longer-term states, so pull them up to the top
17491                    // of the background states, but not all the way to the top state.
17492                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17493                    break;
17494                default:
17495                    // Otherwise, top is a better choice, so take it.
17496                    procState = ActivityManager.PROCESS_STATE_TOP;
17497                    break;
17498            }
17499        }
17500
17501        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
17502            if (app.hasClientActivities) {
17503                // This is a cached process, but with client activities.  Mark it so.
17504                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
17505                app.adjType = "cch-client-act";
17506            } else if (app.treatLikeActivity) {
17507                // This is a cached process, but somebody wants us to treat it like it has
17508                // an activity, okay!
17509                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
17510                app.adjType = "cch-as-act";
17511            }
17512        }
17513
17514        if (adj == ProcessList.SERVICE_ADJ) {
17515            if (doingAll) {
17516                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
17517                mNewNumServiceProcs++;
17518                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
17519                if (!app.serviceb) {
17520                    // This service isn't far enough down on the LRU list to
17521                    // normally be a B service, but if we are low on RAM and it
17522                    // is large we want to force it down since we would prefer to
17523                    // keep launcher over it.
17524                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
17525                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
17526                        app.serviceHighRam = true;
17527                        app.serviceb = true;
17528                        //Slog.i(TAG, "ADJ " + app + " high ram!");
17529                    } else {
17530                        mNewNumAServiceProcs++;
17531                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
17532                    }
17533                } else {
17534                    app.serviceHighRam = false;
17535                }
17536            }
17537            if (app.serviceb) {
17538                adj = ProcessList.SERVICE_B_ADJ;
17539            }
17540        }
17541
17542        app.curRawAdj = adj;
17543
17544        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
17545        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
17546        if (adj > app.maxAdj) {
17547            adj = app.maxAdj;
17548            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
17549                schedGroup = Process.THREAD_GROUP_DEFAULT;
17550            }
17551        }
17552
17553        // Do final modification to adj.  Everything we do between here and applying
17554        // the final setAdj must be done in this function, because we will also use
17555        // it when computing the final cached adj later.  Note that we don't need to
17556        // worry about this for max adj above, since max adj will always be used to
17557        // keep it out of the cached vaues.
17558        app.curAdj = app.modifyRawOomAdj(adj);
17559        app.curSchedGroup = schedGroup;
17560        app.curProcState = procState;
17561        app.foregroundActivities = foregroundActivities;
17562
17563        return app.curRawAdj;
17564    }
17565
17566    /**
17567     * Record new PSS sample for a process.
17568     */
17569    void recordPssSample(ProcessRecord proc, int procState, long pss, long uss, long now) {
17570        proc.lastPssTime = now;
17571        proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
17572        if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
17573                + ": " + pss + " lastPss=" + proc.lastPss
17574                + " state=" + ProcessList.makeProcStateString(procState));
17575        if (proc.initialIdlePss == 0) {
17576            proc.initialIdlePss = pss;
17577        }
17578        proc.lastPss = pss;
17579        if (procState >= ActivityManager.PROCESS_STATE_HOME) {
17580            proc.lastCachedPss = pss;
17581        }
17582    }
17583
17584    /**
17585     * Schedule PSS collection of a process.
17586     */
17587    void requestPssLocked(ProcessRecord proc, int procState) {
17588        if (mPendingPssProcesses.contains(proc)) {
17589            return;
17590        }
17591        if (mPendingPssProcesses.size() == 0) {
17592            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
17593        }
17594        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
17595        proc.pssProcState = procState;
17596        mPendingPssProcesses.add(proc);
17597    }
17598
17599    /**
17600     * Schedule PSS collection of all processes.
17601     */
17602    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
17603        if (!always) {
17604            if (now < (mLastFullPssTime +
17605                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
17606                return;
17607            }
17608        }
17609        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
17610        mLastFullPssTime = now;
17611        mFullPssPending = true;
17612        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
17613        mPendingPssProcesses.clear();
17614        for (int i=mLruProcesses.size()-1; i>=0; i--) {
17615            ProcessRecord app = mLruProcesses.get(i);
17616            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
17617                app.pssProcState = app.setProcState;
17618                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17619                        mTestPssMode, isSleeping(), now);
17620                mPendingPssProcesses.add(app);
17621            }
17622        }
17623        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
17624    }
17625
17626    public void setTestPssMode(boolean enabled) {
17627        synchronized (this) {
17628            mTestPssMode = enabled;
17629            if (enabled) {
17630                // Whenever we enable the mode, we want to take a snapshot all of current
17631                // process mem use.
17632                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
17633            }
17634        }
17635    }
17636
17637    /**
17638     * Ask a given process to GC right now.
17639     */
17640    final void performAppGcLocked(ProcessRecord app) {
17641        try {
17642            app.lastRequestedGc = SystemClock.uptimeMillis();
17643            if (app.thread != null) {
17644                if (app.reportLowMemory) {
17645                    app.reportLowMemory = false;
17646                    app.thread.scheduleLowMemory();
17647                } else {
17648                    app.thread.processInBackground();
17649                }
17650            }
17651        } catch (Exception e) {
17652            // whatever.
17653        }
17654    }
17655
17656    /**
17657     * Returns true if things are idle enough to perform GCs.
17658     */
17659    private final boolean canGcNowLocked() {
17660        boolean processingBroadcasts = false;
17661        for (BroadcastQueue q : mBroadcastQueues) {
17662            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
17663                processingBroadcasts = true;
17664            }
17665        }
17666        return !processingBroadcasts
17667                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
17668    }
17669
17670    /**
17671     * Perform GCs on all processes that are waiting for it, but only
17672     * if things are idle.
17673     */
17674    final void performAppGcsLocked() {
17675        final int N = mProcessesToGc.size();
17676        if (N <= 0) {
17677            return;
17678        }
17679        if (canGcNowLocked()) {
17680            while (mProcessesToGc.size() > 0) {
17681                ProcessRecord proc = mProcessesToGc.remove(0);
17682                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
17683                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
17684                            <= SystemClock.uptimeMillis()) {
17685                        // To avoid spamming the system, we will GC processes one
17686                        // at a time, waiting a few seconds between each.
17687                        performAppGcLocked(proc);
17688                        scheduleAppGcsLocked();
17689                        return;
17690                    } else {
17691                        // It hasn't been long enough since we last GCed this
17692                        // process...  put it in the list to wait for its time.
17693                        addProcessToGcListLocked(proc);
17694                        break;
17695                    }
17696                }
17697            }
17698
17699            scheduleAppGcsLocked();
17700        }
17701    }
17702
17703    /**
17704     * If all looks good, perform GCs on all processes waiting for them.
17705     */
17706    final void performAppGcsIfAppropriateLocked() {
17707        if (canGcNowLocked()) {
17708            performAppGcsLocked();
17709            return;
17710        }
17711        // Still not idle, wait some more.
17712        scheduleAppGcsLocked();
17713    }
17714
17715    /**
17716     * Schedule the execution of all pending app GCs.
17717     */
17718    final void scheduleAppGcsLocked() {
17719        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
17720
17721        if (mProcessesToGc.size() > 0) {
17722            // Schedule a GC for the time to the next process.
17723            ProcessRecord proc = mProcessesToGc.get(0);
17724            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
17725
17726            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
17727            long now = SystemClock.uptimeMillis();
17728            if (when < (now+GC_TIMEOUT)) {
17729                when = now + GC_TIMEOUT;
17730            }
17731            mHandler.sendMessageAtTime(msg, when);
17732        }
17733    }
17734
17735    /**
17736     * Add a process to the array of processes waiting to be GCed.  Keeps the
17737     * list in sorted order by the last GC time.  The process can't already be
17738     * on the list.
17739     */
17740    final void addProcessToGcListLocked(ProcessRecord proc) {
17741        boolean added = false;
17742        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
17743            if (mProcessesToGc.get(i).lastRequestedGc <
17744                    proc.lastRequestedGc) {
17745                added = true;
17746                mProcessesToGc.add(i+1, proc);
17747                break;
17748            }
17749        }
17750        if (!added) {
17751            mProcessesToGc.add(0, proc);
17752        }
17753    }
17754
17755    /**
17756     * Set up to ask a process to GC itself.  This will either do it
17757     * immediately, or put it on the list of processes to gc the next
17758     * time things are idle.
17759     */
17760    final void scheduleAppGcLocked(ProcessRecord app) {
17761        long now = SystemClock.uptimeMillis();
17762        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
17763            return;
17764        }
17765        if (!mProcessesToGc.contains(app)) {
17766            addProcessToGcListLocked(app);
17767            scheduleAppGcsLocked();
17768        }
17769    }
17770
17771    final void checkExcessivePowerUsageLocked(boolean doKills) {
17772        updateCpuStatsNow();
17773
17774        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17775        boolean doWakeKills = doKills;
17776        boolean doCpuKills = doKills;
17777        if (mLastPowerCheckRealtime == 0) {
17778            doWakeKills = false;
17779        }
17780        if (mLastPowerCheckUptime == 0) {
17781            doCpuKills = false;
17782        }
17783        if (stats.isScreenOn()) {
17784            doWakeKills = false;
17785        }
17786        final long curRealtime = SystemClock.elapsedRealtime();
17787        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
17788        final long curUptime = SystemClock.uptimeMillis();
17789        final long uptimeSince = curUptime - mLastPowerCheckUptime;
17790        mLastPowerCheckRealtime = curRealtime;
17791        mLastPowerCheckUptime = curUptime;
17792        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
17793            doWakeKills = false;
17794        }
17795        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
17796            doCpuKills = false;
17797        }
17798        int i = mLruProcesses.size();
17799        while (i > 0) {
17800            i--;
17801            ProcessRecord app = mLruProcesses.get(i);
17802            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17803                long wtime;
17804                synchronized (stats) {
17805                    wtime = stats.getProcessWakeTime(app.info.uid,
17806                            app.pid, curRealtime);
17807                }
17808                long wtimeUsed = wtime - app.lastWakeTime;
17809                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
17810                if (DEBUG_POWER) {
17811                    StringBuilder sb = new StringBuilder(128);
17812                    sb.append("Wake for ");
17813                    app.toShortString(sb);
17814                    sb.append(": over ");
17815                    TimeUtils.formatDuration(realtimeSince, sb);
17816                    sb.append(" used ");
17817                    TimeUtils.formatDuration(wtimeUsed, sb);
17818                    sb.append(" (");
17819                    sb.append((wtimeUsed*100)/realtimeSince);
17820                    sb.append("%)");
17821                    Slog.i(TAG, sb.toString());
17822                    sb.setLength(0);
17823                    sb.append("CPU for ");
17824                    app.toShortString(sb);
17825                    sb.append(": over ");
17826                    TimeUtils.formatDuration(uptimeSince, sb);
17827                    sb.append(" used ");
17828                    TimeUtils.formatDuration(cputimeUsed, sb);
17829                    sb.append(" (");
17830                    sb.append((cputimeUsed*100)/uptimeSince);
17831                    sb.append("%)");
17832                    Slog.i(TAG, sb.toString());
17833                }
17834                // If a process has held a wake lock for more
17835                // than 50% of the time during this period,
17836                // that sounds bad.  Kill!
17837                if (doWakeKills && realtimeSince > 0
17838                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
17839                    synchronized (stats) {
17840                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
17841                                realtimeSince, wtimeUsed);
17842                    }
17843                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
17844                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
17845                } else if (doCpuKills && uptimeSince > 0
17846                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
17847                    synchronized (stats) {
17848                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
17849                                uptimeSince, cputimeUsed);
17850                    }
17851                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
17852                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
17853                } else {
17854                    app.lastWakeTime = wtime;
17855                    app.lastCpuTime = app.curCpuTime;
17856                }
17857            }
17858        }
17859    }
17860
17861    private final boolean applyOomAdjLocked(ProcessRecord app,
17862            ProcessRecord TOP_APP, boolean doingAll, long now) {
17863        boolean success = true;
17864
17865        if (app.curRawAdj != app.setRawAdj) {
17866            app.setRawAdj = app.curRawAdj;
17867        }
17868
17869        int changes = 0;
17870
17871        if (app.curAdj != app.setAdj) {
17872            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
17873            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
17874                TAG, "Set " + app.pid + " " + app.processName +
17875                " adj " + app.curAdj + ": " + app.adjType);
17876            app.setAdj = app.curAdj;
17877        }
17878
17879        if (app.setSchedGroup != app.curSchedGroup) {
17880            app.setSchedGroup = app.curSchedGroup;
17881            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17882                    "Setting process group of " + app.processName
17883                    + " to " + app.curSchedGroup);
17884            if (app.waitingToKill != null &&
17885                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
17886                app.kill(app.waitingToKill, true);
17887                success = false;
17888            } else {
17889                if (true) {
17890                    long oldId = Binder.clearCallingIdentity();
17891                    try {
17892                        Process.setProcessGroup(app.pid, app.curSchedGroup);
17893                    } catch (Exception e) {
17894                        Slog.w(TAG, "Failed setting process group of " + app.pid
17895                                + " to " + app.curSchedGroup);
17896                        e.printStackTrace();
17897                    } finally {
17898                        Binder.restoreCallingIdentity(oldId);
17899                    }
17900                } else {
17901                    if (app.thread != null) {
17902                        try {
17903                            app.thread.setSchedulingGroup(app.curSchedGroup);
17904                        } catch (RemoteException e) {
17905                        }
17906                    }
17907                }
17908                Process.setSwappiness(app.pid,
17909                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
17910            }
17911        }
17912        if (app.repForegroundActivities != app.foregroundActivities) {
17913            app.repForegroundActivities = app.foregroundActivities;
17914            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
17915        }
17916        if (app.repProcState != app.curProcState) {
17917            app.repProcState = app.curProcState;
17918            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
17919            if (app.thread != null) {
17920                try {
17921                    if (false) {
17922                        //RuntimeException h = new RuntimeException("here");
17923                        Slog.i(TAG, "Sending new process state " + app.repProcState
17924                                + " to " + app /*, h*/);
17925                    }
17926                    app.thread.setProcessState(app.repProcState);
17927                } catch (RemoteException e) {
17928                }
17929            }
17930        }
17931        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
17932                app.setProcState)) {
17933            if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
17934                // Experimental code to more aggressively collect pss while
17935                // running test...  the problem is that this tends to collect
17936                // the data right when a process is transitioning between process
17937                // states, which well tend to give noisy data.
17938                long start = SystemClock.uptimeMillis();
17939                long pss = Debug.getPss(app.pid, mTmpLong, null);
17940                recordPssSample(app, app.curProcState, pss, mTmpLong[0], now);
17941                mPendingPssProcesses.remove(app);
17942                Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
17943                        + " to " + app.curProcState + ": "
17944                        + (SystemClock.uptimeMillis()-start) + "ms");
17945            }
17946            app.lastStateTime = now;
17947            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17948                    mTestPssMode, isSleeping(), now);
17949            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
17950                    + ProcessList.makeProcStateString(app.setProcState) + " to "
17951                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
17952                    + (app.nextPssTime-now) + ": " + app);
17953        } else {
17954            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
17955                    && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
17956                    mTestPssMode)))) {
17957                requestPssLocked(app, app.setProcState);
17958                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
17959                        mTestPssMode, isSleeping(), now);
17960            } else if (false && DEBUG_PSS) {
17961                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
17962            }
17963        }
17964        if (app.setProcState != app.curProcState) {
17965            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17966                    "Proc state change of " + app.processName
17967                    + " to " + app.curProcState);
17968            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
17969            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
17970            if (setImportant && !curImportant) {
17971                // This app is no longer something we consider important enough to allow to
17972                // use arbitrary amounts of battery power.  Note
17973                // its current wake lock time to later know to kill it if
17974                // it is not behaving well.
17975                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17976                synchronized (stats) {
17977                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
17978                            app.pid, SystemClock.elapsedRealtime());
17979                }
17980                app.lastCpuTime = app.curCpuTime;
17981
17982            }
17983            app.setProcState = app.curProcState;
17984            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17985                app.notCachedSinceIdle = false;
17986            }
17987            if (!doingAll) {
17988                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
17989            } else {
17990                app.procStateChanged = true;
17991            }
17992        }
17993
17994        if (changes != 0) {
17995            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
17996            int i = mPendingProcessChanges.size()-1;
17997            ProcessChangeItem item = null;
17998            while (i >= 0) {
17999                item = mPendingProcessChanges.get(i);
18000                if (item.pid == app.pid) {
18001                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
18002                    break;
18003                }
18004                i--;
18005            }
18006            if (i < 0) {
18007                // No existing item in pending changes; need a new one.
18008                final int NA = mAvailProcessChanges.size();
18009                if (NA > 0) {
18010                    item = mAvailProcessChanges.remove(NA-1);
18011                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
18012                } else {
18013                    item = new ProcessChangeItem();
18014                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
18015                }
18016                item.changes = 0;
18017                item.pid = app.pid;
18018                item.uid = app.info.uid;
18019                if (mPendingProcessChanges.size() == 0) {
18020                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
18021                            "*** Enqueueing dispatch processes changed!");
18022                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
18023                }
18024                mPendingProcessChanges.add(item);
18025            }
18026            item.changes |= changes;
18027            item.processState = app.repProcState;
18028            item.foregroundActivities = app.repForegroundActivities;
18029            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
18030                    + Integer.toHexString(System.identityHashCode(item))
18031                    + " " + app.toShortString() + ": changes=" + item.changes
18032                    + " procState=" + item.processState
18033                    + " foreground=" + item.foregroundActivities
18034                    + " type=" + app.adjType + " source=" + app.adjSource
18035                    + " target=" + app.adjTarget);
18036        }
18037
18038        return success;
18039    }
18040
18041    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
18042        if (proc.thread != null) {
18043            if (proc.baseProcessTracker != null) {
18044                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
18045            }
18046            if (proc.repProcState >= 0) {
18047                mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
18048                        proc.repProcState);
18049            }
18050        }
18051    }
18052
18053    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
18054            ProcessRecord TOP_APP, boolean doingAll, long now) {
18055        if (app.thread == null) {
18056            return false;
18057        }
18058
18059        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
18060
18061        return applyOomAdjLocked(app, TOP_APP, doingAll, now);
18062    }
18063
18064    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
18065            boolean oomAdj) {
18066        if (isForeground != proc.foregroundServices) {
18067            proc.foregroundServices = isForeground;
18068            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
18069                    proc.info.uid);
18070            if (isForeground) {
18071                if (curProcs == null) {
18072                    curProcs = new ArrayList<ProcessRecord>();
18073                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
18074                }
18075                if (!curProcs.contains(proc)) {
18076                    curProcs.add(proc);
18077                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
18078                            proc.info.packageName, proc.info.uid);
18079                }
18080            } else {
18081                if (curProcs != null) {
18082                    if (curProcs.remove(proc)) {
18083                        mBatteryStatsService.noteEvent(
18084                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
18085                                proc.info.packageName, proc.info.uid);
18086                        if (curProcs.size() <= 0) {
18087                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
18088                        }
18089                    }
18090                }
18091            }
18092            if (oomAdj) {
18093                updateOomAdjLocked();
18094            }
18095        }
18096    }
18097
18098    private final ActivityRecord resumedAppLocked() {
18099        ActivityRecord act = mStackSupervisor.resumedAppLocked();
18100        String pkg;
18101        int uid;
18102        if (act != null) {
18103            pkg = act.packageName;
18104            uid = act.info.applicationInfo.uid;
18105        } else {
18106            pkg = null;
18107            uid = -1;
18108        }
18109        // Has the UID or resumed package name changed?
18110        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
18111                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
18112            if (mCurResumedPackage != null) {
18113                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
18114                        mCurResumedPackage, mCurResumedUid);
18115            }
18116            mCurResumedPackage = pkg;
18117            mCurResumedUid = uid;
18118            if (mCurResumedPackage != null) {
18119                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
18120                        mCurResumedPackage, mCurResumedUid);
18121            }
18122        }
18123        return act;
18124    }
18125
18126    final boolean updateOomAdjLocked(ProcessRecord app) {
18127        final ActivityRecord TOP_ACT = resumedAppLocked();
18128        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
18129        final boolean wasCached = app.cached;
18130
18131        mAdjSeq++;
18132
18133        // This is the desired cached adjusment we want to tell it to use.
18134        // If our app is currently cached, we know it, and that is it.  Otherwise,
18135        // we don't know it yet, and it needs to now be cached we will then
18136        // need to do a complete oom adj.
18137        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
18138                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
18139        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
18140                SystemClock.uptimeMillis());
18141        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
18142            // Changed to/from cached state, so apps after it in the LRU
18143            // list may also be changed.
18144            updateOomAdjLocked();
18145        }
18146        return success;
18147    }
18148
18149    final void updateOomAdjLocked() {
18150        final ActivityRecord TOP_ACT = resumedAppLocked();
18151        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
18152        final long now = SystemClock.uptimeMillis();
18153        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
18154        final int N = mLruProcesses.size();
18155
18156        if (false) {
18157            RuntimeException e = new RuntimeException();
18158            e.fillInStackTrace();
18159            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
18160        }
18161
18162        mAdjSeq++;
18163        mNewNumServiceProcs = 0;
18164        mNewNumAServiceProcs = 0;
18165
18166        final int emptyProcessLimit;
18167        final int cachedProcessLimit;
18168        if (mProcessLimit <= 0) {
18169            emptyProcessLimit = cachedProcessLimit = 0;
18170        } else if (mProcessLimit == 1) {
18171            emptyProcessLimit = 1;
18172            cachedProcessLimit = 0;
18173        } else {
18174            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
18175            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
18176        }
18177
18178        // Let's determine how many processes we have running vs.
18179        // how many slots we have for background processes; we may want
18180        // to put multiple processes in a slot of there are enough of
18181        // them.
18182        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
18183                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
18184        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
18185        if (numEmptyProcs > cachedProcessLimit) {
18186            // If there are more empty processes than our limit on cached
18187            // processes, then use the cached process limit for the factor.
18188            // This ensures that the really old empty processes get pushed
18189            // down to the bottom, so if we are running low on memory we will
18190            // have a better chance at keeping around more cached processes
18191            // instead of a gazillion empty processes.
18192            numEmptyProcs = cachedProcessLimit;
18193        }
18194        int emptyFactor = numEmptyProcs/numSlots;
18195        if (emptyFactor < 1) emptyFactor = 1;
18196        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
18197        if (cachedFactor < 1) cachedFactor = 1;
18198        int stepCached = 0;
18199        int stepEmpty = 0;
18200        int numCached = 0;
18201        int numEmpty = 0;
18202        int numTrimming = 0;
18203
18204        mNumNonCachedProcs = 0;
18205        mNumCachedHiddenProcs = 0;
18206
18207        // First update the OOM adjustment for each of the
18208        // application processes based on their current state.
18209        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
18210        int nextCachedAdj = curCachedAdj+1;
18211        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
18212        int nextEmptyAdj = curEmptyAdj+2;
18213        for (int i=N-1; i>=0; i--) {
18214            ProcessRecord app = mLruProcesses.get(i);
18215            if (!app.killedByAm && app.thread != null) {
18216                app.procStateChanged = false;
18217                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
18218
18219                // If we haven't yet assigned the final cached adj
18220                // to the process, do that now.
18221                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
18222                    switch (app.curProcState) {
18223                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
18224                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
18225                            // This process is a cached process holding activities...
18226                            // assign it the next cached value for that type, and then
18227                            // step that cached level.
18228                            app.curRawAdj = curCachedAdj;
18229                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
18230                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
18231                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
18232                                    + ")");
18233                            if (curCachedAdj != nextCachedAdj) {
18234                                stepCached++;
18235                                if (stepCached >= cachedFactor) {
18236                                    stepCached = 0;
18237                                    curCachedAdj = nextCachedAdj;
18238                                    nextCachedAdj += 2;
18239                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
18240                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
18241                                    }
18242                                }
18243                            }
18244                            break;
18245                        default:
18246                            // For everything else, assign next empty cached process
18247                            // level and bump that up.  Note that this means that
18248                            // long-running services that have dropped down to the
18249                            // cached level will be treated as empty (since their process
18250                            // state is still as a service), which is what we want.
18251                            app.curRawAdj = curEmptyAdj;
18252                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
18253                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
18254                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
18255                                    + ")");
18256                            if (curEmptyAdj != nextEmptyAdj) {
18257                                stepEmpty++;
18258                                if (stepEmpty >= emptyFactor) {
18259                                    stepEmpty = 0;
18260                                    curEmptyAdj = nextEmptyAdj;
18261                                    nextEmptyAdj += 2;
18262                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
18263                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
18264                                    }
18265                                }
18266                            }
18267                            break;
18268                    }
18269                }
18270
18271                applyOomAdjLocked(app, TOP_APP, true, now);
18272
18273                // Count the number of process types.
18274                switch (app.curProcState) {
18275                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
18276                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
18277                        mNumCachedHiddenProcs++;
18278                        numCached++;
18279                        if (numCached > cachedProcessLimit) {
18280                            app.kill("cached #" + numCached, true);
18281                        }
18282                        break;
18283                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
18284                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
18285                                && app.lastActivityTime < oldTime) {
18286                            app.kill("empty for "
18287                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
18288                                    / 1000) + "s", true);
18289                        } else {
18290                            numEmpty++;
18291                            if (numEmpty > emptyProcessLimit) {
18292                                app.kill("empty #" + numEmpty, true);
18293                            }
18294                        }
18295                        break;
18296                    default:
18297                        mNumNonCachedProcs++;
18298                        break;
18299                }
18300
18301                if (app.isolated && app.services.size() <= 0) {
18302                    // If this is an isolated process, and there are no
18303                    // services running in it, then the process is no longer
18304                    // needed.  We agressively kill these because we can by
18305                    // definition not re-use the same process again, and it is
18306                    // good to avoid having whatever code was running in them
18307                    // left sitting around after no longer needed.
18308                    app.kill("isolated not needed", true);
18309                }
18310
18311                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
18312                        && !app.killedByAm) {
18313                    numTrimming++;
18314                }
18315            }
18316        }
18317
18318        mNumServiceProcs = mNewNumServiceProcs;
18319
18320        // Now determine the memory trimming level of background processes.
18321        // Unfortunately we need to start at the back of the list to do this
18322        // properly.  We only do this if the number of background apps we
18323        // are managing to keep around is less than half the maximum we desire;
18324        // if we are keeping a good number around, we'll let them use whatever
18325        // memory they want.
18326        final int numCachedAndEmpty = numCached + numEmpty;
18327        int memFactor;
18328        if (numCached <= ProcessList.TRIM_CACHED_APPS
18329                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
18330            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
18331                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
18332            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
18333                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
18334            } else {
18335                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
18336            }
18337        } else {
18338            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
18339        }
18340        // We always allow the memory level to go up (better).  We only allow it to go
18341        // down if we are in a state where that is allowed, *and* the total number of processes
18342        // has gone down since last time.
18343        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
18344                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
18345                + " last=" + mLastNumProcesses);
18346        if (memFactor > mLastMemoryLevel) {
18347            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
18348                memFactor = mLastMemoryLevel;
18349                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
18350            }
18351        }
18352        mLastMemoryLevel = memFactor;
18353        mLastNumProcesses = mLruProcesses.size();
18354        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
18355        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
18356        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
18357            if (mLowRamStartTime == 0) {
18358                mLowRamStartTime = now;
18359            }
18360            int step = 0;
18361            int fgTrimLevel;
18362            switch (memFactor) {
18363                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
18364                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
18365                    break;
18366                case ProcessStats.ADJ_MEM_FACTOR_LOW:
18367                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
18368                    break;
18369                default:
18370                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
18371                    break;
18372            }
18373            int factor = numTrimming/3;
18374            int minFactor = 2;
18375            if (mHomeProcess != null) minFactor++;
18376            if (mPreviousProcess != null) minFactor++;
18377            if (factor < minFactor) factor = minFactor;
18378            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
18379            for (int i=N-1; i>=0; i--) {
18380                ProcessRecord app = mLruProcesses.get(i);
18381                if (allChanged || app.procStateChanged) {
18382                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
18383                    app.procStateChanged = false;
18384                }
18385                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
18386                        && !app.killedByAm) {
18387                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
18388                        try {
18389                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18390                                    "Trimming memory of " + app.processName
18391                                    + " to " + curLevel);
18392                            app.thread.scheduleTrimMemory(curLevel);
18393                        } catch (RemoteException e) {
18394                        }
18395                        if (false) {
18396                            // For now we won't do this; our memory trimming seems
18397                            // to be good enough at this point that destroying
18398                            // activities causes more harm than good.
18399                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
18400                                    && app != mHomeProcess && app != mPreviousProcess) {
18401                                // Need to do this on its own message because the stack may not
18402                                // be in a consistent state at this point.
18403                                // For these apps we will also finish their activities
18404                                // to help them free memory.
18405                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
18406                            }
18407                        }
18408                    }
18409                    app.trimMemoryLevel = curLevel;
18410                    step++;
18411                    if (step >= factor) {
18412                        step = 0;
18413                        switch (curLevel) {
18414                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
18415                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
18416                                break;
18417                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
18418                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
18419                                break;
18420                        }
18421                    }
18422                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
18423                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
18424                            && app.thread != null) {
18425                        try {
18426                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18427                                    "Trimming memory of heavy-weight " + app.processName
18428                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
18429                            app.thread.scheduleTrimMemory(
18430                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
18431                        } catch (RemoteException e) {
18432                        }
18433                    }
18434                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
18435                } else {
18436                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
18437                            || app.systemNoUi) && app.pendingUiClean) {
18438                        // If this application is now in the background and it
18439                        // had done UI, then give it the special trim level to
18440                        // have it free UI resources.
18441                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
18442                        if (app.trimMemoryLevel < level && app.thread != null) {
18443                            try {
18444                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18445                                        "Trimming memory of bg-ui " + app.processName
18446                                        + " to " + level);
18447                                app.thread.scheduleTrimMemory(level);
18448                            } catch (RemoteException e) {
18449                            }
18450                        }
18451                        app.pendingUiClean = false;
18452                    }
18453                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
18454                        try {
18455                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18456                                    "Trimming memory of fg " + app.processName
18457                                    + " to " + fgTrimLevel);
18458                            app.thread.scheduleTrimMemory(fgTrimLevel);
18459                        } catch (RemoteException e) {
18460                        }
18461                    }
18462                    app.trimMemoryLevel = fgTrimLevel;
18463                }
18464            }
18465        } else {
18466            if (mLowRamStartTime != 0) {
18467                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
18468                mLowRamStartTime = 0;
18469            }
18470            for (int i=N-1; i>=0; i--) {
18471                ProcessRecord app = mLruProcesses.get(i);
18472                if (allChanged || app.procStateChanged) {
18473                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
18474                    app.procStateChanged = false;
18475                }
18476                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
18477                        || app.systemNoUi) && app.pendingUiClean) {
18478                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
18479                            && app.thread != null) {
18480                        try {
18481                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18482                                    "Trimming memory of ui hidden " + app.processName
18483                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
18484                            app.thread.scheduleTrimMemory(
18485                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
18486                        } catch (RemoteException e) {
18487                        }
18488                    }
18489                    app.pendingUiClean = false;
18490                }
18491                app.trimMemoryLevel = 0;
18492            }
18493        }
18494
18495        if (mAlwaysFinishActivities) {
18496            // Need to do this on its own message because the stack may not
18497            // be in a consistent state at this point.
18498            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
18499        }
18500
18501        if (allChanged) {
18502            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
18503        }
18504
18505        if (mProcessStats.shouldWriteNowLocked(now)) {
18506            mHandler.post(new Runnable() {
18507                @Override public void run() {
18508                    synchronized (ActivityManagerService.this) {
18509                        mProcessStats.writeStateAsyncLocked();
18510                    }
18511                }
18512            });
18513        }
18514
18515        if (DEBUG_OOM_ADJ) {
18516            if (false) {
18517                RuntimeException here = new RuntimeException("here");
18518                here.fillInStackTrace();
18519                Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms", here);
18520            } else {
18521                Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
18522            }
18523        }
18524    }
18525
18526    final void trimApplications() {
18527        synchronized (this) {
18528            int i;
18529
18530            // First remove any unused application processes whose package
18531            // has been removed.
18532            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
18533                final ProcessRecord app = mRemovedProcesses.get(i);
18534                if (app.activities.size() == 0
18535                        && app.curReceiver == null && app.services.size() == 0) {
18536                    Slog.i(
18537                        TAG, "Exiting empty application process "
18538                        + app.processName + " ("
18539                        + (app.thread != null ? app.thread.asBinder() : null)
18540                        + ")\n");
18541                    if (app.pid > 0 && app.pid != MY_PID) {
18542                        app.kill("empty", false);
18543                    } else {
18544                        try {
18545                            app.thread.scheduleExit();
18546                        } catch (Exception e) {
18547                            // Ignore exceptions.
18548                        }
18549                    }
18550                    cleanUpApplicationRecordLocked(app, false, true, -1);
18551                    mRemovedProcesses.remove(i);
18552
18553                    if (app.persistent) {
18554                        addAppLocked(app.info, false, null /* ABI override */);
18555                    }
18556                }
18557            }
18558
18559            // Now update the oom adj for all processes.
18560            updateOomAdjLocked();
18561        }
18562    }
18563
18564    /** This method sends the specified signal to each of the persistent apps */
18565    public void signalPersistentProcesses(int sig) throws RemoteException {
18566        if (sig != Process.SIGNAL_USR1) {
18567            throw new SecurityException("Only SIGNAL_USR1 is allowed");
18568        }
18569
18570        synchronized (this) {
18571            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
18572                    != PackageManager.PERMISSION_GRANTED) {
18573                throw new SecurityException("Requires permission "
18574                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
18575            }
18576
18577            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
18578                ProcessRecord r = mLruProcesses.get(i);
18579                if (r.thread != null && r.persistent) {
18580                    Process.sendSignal(r.pid, sig);
18581                }
18582            }
18583        }
18584    }
18585
18586    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
18587        if (proc == null || proc == mProfileProc) {
18588            proc = mProfileProc;
18589            profileType = mProfileType;
18590            clearProfilerLocked();
18591        }
18592        if (proc == null) {
18593            return;
18594        }
18595        try {
18596            proc.thread.profilerControl(false, null, profileType);
18597        } catch (RemoteException e) {
18598            throw new IllegalStateException("Process disappeared");
18599        }
18600    }
18601
18602    private void clearProfilerLocked() {
18603        if (mProfileFd != null) {
18604            try {
18605                mProfileFd.close();
18606            } catch (IOException e) {
18607            }
18608        }
18609        mProfileApp = null;
18610        mProfileProc = null;
18611        mProfileFile = null;
18612        mProfileType = 0;
18613        mAutoStopProfiler = false;
18614        mSamplingInterval = 0;
18615    }
18616
18617    public boolean profileControl(String process, int userId, boolean start,
18618            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
18619
18620        try {
18621            synchronized (this) {
18622                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
18623                // its own permission.
18624                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
18625                        != PackageManager.PERMISSION_GRANTED) {
18626                    throw new SecurityException("Requires permission "
18627                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
18628                }
18629
18630                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
18631                    throw new IllegalArgumentException("null profile info or fd");
18632                }
18633
18634                ProcessRecord proc = null;
18635                if (process != null) {
18636                    proc = findProcessLocked(process, userId, "profileControl");
18637                }
18638
18639                if (start && (proc == null || proc.thread == null)) {
18640                    throw new IllegalArgumentException("Unknown process: " + process);
18641                }
18642
18643                if (start) {
18644                    stopProfilerLocked(null, 0);
18645                    setProfileApp(proc.info, proc.processName, profilerInfo);
18646                    mProfileProc = proc;
18647                    mProfileType = profileType;
18648                    ParcelFileDescriptor fd = profilerInfo.profileFd;
18649                    try {
18650                        fd = fd.dup();
18651                    } catch (IOException e) {
18652                        fd = null;
18653                    }
18654                    profilerInfo.profileFd = fd;
18655                    proc.thread.profilerControl(start, profilerInfo, profileType);
18656                    fd = null;
18657                    mProfileFd = null;
18658                } else {
18659                    stopProfilerLocked(proc, profileType);
18660                    if (profilerInfo != null && profilerInfo.profileFd != null) {
18661                        try {
18662                            profilerInfo.profileFd.close();
18663                        } catch (IOException e) {
18664                        }
18665                    }
18666                }
18667
18668                return true;
18669            }
18670        } catch (RemoteException e) {
18671            throw new IllegalStateException("Process disappeared");
18672        } finally {
18673            if (profilerInfo != null && profilerInfo.profileFd != null) {
18674                try {
18675                    profilerInfo.profileFd.close();
18676                } catch (IOException e) {
18677                }
18678            }
18679        }
18680    }
18681
18682    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
18683        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18684                userId, true, ALLOW_FULL_ONLY, callName, null);
18685        ProcessRecord proc = null;
18686        try {
18687            int pid = Integer.parseInt(process);
18688            synchronized (mPidsSelfLocked) {
18689                proc = mPidsSelfLocked.get(pid);
18690            }
18691        } catch (NumberFormatException e) {
18692        }
18693
18694        if (proc == null) {
18695            ArrayMap<String, SparseArray<ProcessRecord>> all
18696                    = mProcessNames.getMap();
18697            SparseArray<ProcessRecord> procs = all.get(process);
18698            if (procs != null && procs.size() > 0) {
18699                proc = procs.valueAt(0);
18700                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
18701                    for (int i=1; i<procs.size(); i++) {
18702                        ProcessRecord thisProc = procs.valueAt(i);
18703                        if (thisProc.userId == userId) {
18704                            proc = thisProc;
18705                            break;
18706                        }
18707                    }
18708                }
18709            }
18710        }
18711
18712        return proc;
18713    }
18714
18715    public boolean dumpHeap(String process, int userId, boolean managed,
18716            String path, ParcelFileDescriptor fd) throws RemoteException {
18717
18718        try {
18719            synchronized (this) {
18720                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
18721                // its own permission (same as profileControl).
18722                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
18723                        != PackageManager.PERMISSION_GRANTED) {
18724                    throw new SecurityException("Requires permission "
18725                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
18726                }
18727
18728                if (fd == null) {
18729                    throw new IllegalArgumentException("null fd");
18730                }
18731
18732                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
18733                if (proc == null || proc.thread == null) {
18734                    throw new IllegalArgumentException("Unknown process: " + process);
18735                }
18736
18737                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
18738                if (!isDebuggable) {
18739                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
18740                        throw new SecurityException("Process not debuggable: " + proc);
18741                    }
18742                }
18743
18744                proc.thread.dumpHeap(managed, path, fd);
18745                fd = null;
18746                return true;
18747            }
18748        } catch (RemoteException e) {
18749            throw new IllegalStateException("Process disappeared");
18750        } finally {
18751            if (fd != null) {
18752                try {
18753                    fd.close();
18754                } catch (IOException e) {
18755                }
18756            }
18757        }
18758    }
18759
18760    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
18761    public void monitor() {
18762        synchronized (this) { }
18763    }
18764
18765    void onCoreSettingsChange(Bundle settings) {
18766        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
18767            ProcessRecord processRecord = mLruProcesses.get(i);
18768            try {
18769                if (processRecord.thread != null) {
18770                    processRecord.thread.setCoreSettings(settings);
18771                }
18772            } catch (RemoteException re) {
18773                /* ignore */
18774            }
18775        }
18776    }
18777
18778    // Multi-user methods
18779
18780    /**
18781     * Start user, if its not already running, but don't bring it to foreground.
18782     */
18783    @Override
18784    public boolean startUserInBackground(final int userId) {
18785        return startUser(userId, /* foreground */ false);
18786    }
18787
18788    /**
18789     * Start user, if its not already running, and bring it to foreground.
18790     */
18791    boolean startUserInForeground(final int userId, Dialog dlg) {
18792        boolean result = startUser(userId, /* foreground */ true);
18793        dlg.dismiss();
18794        return result;
18795    }
18796
18797    /**
18798     * Refreshes the list of users related to the current user when either a
18799     * user switch happens or when a new related user is started in the
18800     * background.
18801     */
18802    private void updateCurrentProfileIdsLocked() {
18803        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18804                mCurrentUserId, false /* enabledOnly */);
18805        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
18806        for (int i = 0; i < currentProfileIds.length; i++) {
18807            currentProfileIds[i] = profiles.get(i).id;
18808        }
18809        mCurrentProfileIds = currentProfileIds;
18810
18811        synchronized (mUserProfileGroupIdsSelfLocked) {
18812            mUserProfileGroupIdsSelfLocked.clear();
18813            final List<UserInfo> users = getUserManagerLocked().getUsers(false);
18814            for (int i = 0; i < users.size(); i++) {
18815                UserInfo user = users.get(i);
18816                if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
18817                    mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
18818                }
18819            }
18820        }
18821    }
18822
18823    private Set getProfileIdsLocked(int userId) {
18824        Set userIds = new HashSet<Integer>();
18825        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18826                userId, false /* enabledOnly */);
18827        for (UserInfo user : profiles) {
18828            userIds.add(Integer.valueOf(user.id));
18829        }
18830        return userIds;
18831    }
18832
18833    @Override
18834    public boolean switchUser(final int userId) {
18835        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
18836        String userName;
18837        synchronized (this) {
18838            UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18839            if (userInfo == null) {
18840                Slog.w(TAG, "No user info for user #" + userId);
18841                return false;
18842            }
18843            if (userInfo.isManagedProfile()) {
18844                Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18845                return false;
18846            }
18847            userName = userInfo.name;
18848            mTargetUserId = userId;
18849        }
18850        mHandler.removeMessages(START_USER_SWITCH_MSG);
18851        mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName));
18852        return true;
18853    }
18854
18855    private void showUserSwitchDialog(int userId, String userName) {
18856        // The dialog will show and then initiate the user switch by calling startUserInForeground
18857        Dialog d = new UserSwitchingDialog(this, mContext, userId, userName,
18858                true /* above system */);
18859        d.show();
18860    }
18861
18862    private boolean startUser(final int userId, final boolean foreground) {
18863        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18864                != PackageManager.PERMISSION_GRANTED) {
18865            String msg = "Permission Denial: switchUser() from pid="
18866                    + Binder.getCallingPid()
18867                    + ", uid=" + Binder.getCallingUid()
18868                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18869            Slog.w(TAG, msg);
18870            throw new SecurityException(msg);
18871        }
18872
18873        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
18874
18875        final long ident = Binder.clearCallingIdentity();
18876        try {
18877            synchronized (this) {
18878                final int oldUserId = mCurrentUserId;
18879                if (oldUserId == userId) {
18880                    return true;
18881                }
18882
18883                mStackSupervisor.setLockTaskModeLocked(null, false);
18884
18885                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18886                if (userInfo == null) {
18887                    Slog.w(TAG, "No user info for user #" + userId);
18888                    return false;
18889                }
18890                if (foreground && userInfo.isManagedProfile()) {
18891                    Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18892                    return false;
18893                }
18894
18895                if (foreground) {
18896                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
18897                            R.anim.screen_user_enter);
18898                }
18899
18900                boolean needStart = false;
18901
18902                // If the user we are switching to is not currently started, then
18903                // we need to start it now.
18904                if (mStartedUsers.get(userId) == null) {
18905                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
18906                    updateStartedUserArrayLocked();
18907                    needStart = true;
18908                }
18909
18910                final Integer userIdInt = Integer.valueOf(userId);
18911                mUserLru.remove(userIdInt);
18912                mUserLru.add(userIdInt);
18913
18914                if (foreground) {
18915                    mCurrentUserId = userId;
18916                    mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up
18917                    updateCurrentProfileIdsLocked();
18918                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
18919                    // Once the internal notion of the active user has switched, we lock the device
18920                    // with the option to show the user switcher on the keyguard.
18921                    mWindowManager.lockNow(null);
18922                } else {
18923                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
18924                    updateCurrentProfileIdsLocked();
18925                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
18926                    mUserLru.remove(currentUserIdInt);
18927                    mUserLru.add(currentUserIdInt);
18928                }
18929
18930                final UserStartedState uss = mStartedUsers.get(userId);
18931
18932                // Make sure user is in the started state.  If it is currently
18933                // stopping, we need to knock that off.
18934                if (uss.mState == UserStartedState.STATE_STOPPING) {
18935                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
18936                    // so we can just fairly silently bring the user back from
18937                    // the almost-dead.
18938                    uss.mState = UserStartedState.STATE_RUNNING;
18939                    updateStartedUserArrayLocked();
18940                    needStart = true;
18941                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
18942                    // This means ACTION_SHUTDOWN has been sent, so we will
18943                    // need to treat this as a new boot of the user.
18944                    uss.mState = UserStartedState.STATE_BOOTING;
18945                    updateStartedUserArrayLocked();
18946                    needStart = true;
18947                }
18948
18949                if (uss.mState == UserStartedState.STATE_BOOTING) {
18950                    // Booting up a new user, need to tell system services about it.
18951                    // Note that this is on the same handler as scheduling of broadcasts,
18952                    // which is important because it needs to go first.
18953                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
18954                }
18955
18956                if (foreground) {
18957                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
18958                            oldUserId));
18959                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
18960                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18961                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
18962                            oldUserId, userId, uss));
18963                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
18964                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
18965                }
18966
18967                if (needStart) {
18968                    // Send USER_STARTED broadcast
18969                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
18970                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18971                            | Intent.FLAG_RECEIVER_FOREGROUND);
18972                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18973                    broadcastIntentLocked(null, null, intent,
18974                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18975                            false, false, MY_PID, Process.SYSTEM_UID, userId);
18976                }
18977
18978                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
18979                    if (userId != UserHandle.USER_OWNER) {
18980                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
18981                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18982                        broadcastIntentLocked(null, null, intent, null,
18983                                new IIntentReceiver.Stub() {
18984                                    public void performReceive(Intent intent, int resultCode,
18985                                            String data, Bundle extras, boolean ordered,
18986                                            boolean sticky, int sendingUser) {
18987                                        onUserInitialized(uss, foreground, oldUserId, userId);
18988                                    }
18989                                }, 0, null, null, null, AppOpsManager.OP_NONE,
18990                                true, false, MY_PID, Process.SYSTEM_UID,
18991                                userId);
18992                        uss.initializing = true;
18993                    } else {
18994                        getUserManagerLocked().makeInitialized(userInfo.id);
18995                    }
18996                }
18997
18998                if (foreground) {
18999                    if (!uss.initializing) {
19000                        moveUserToForeground(uss, oldUserId, userId);
19001                    }
19002                } else {
19003                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
19004                }
19005
19006                if (needStart) {
19007                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
19008                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19009                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
19010                    broadcastIntentLocked(null, null, intent,
19011                            null, new IIntentReceiver.Stub() {
19012                                @Override
19013                                public void performReceive(Intent intent, int resultCode, String data,
19014                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
19015                                        throws RemoteException {
19016                                }
19017                            }, 0, null, null,
19018                            INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
19019                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
19020                }
19021            }
19022        } finally {
19023            Binder.restoreCallingIdentity(ident);
19024        }
19025
19026        return true;
19027    }
19028
19029    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
19030        long ident = Binder.clearCallingIdentity();
19031        try {
19032            Intent intent;
19033            if (oldUserId >= 0) {
19034                // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
19035                List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
19036                int count = profiles.size();
19037                for (int i = 0; i < count; i++) {
19038                    int profileUserId = profiles.get(i).id;
19039                    intent = new Intent(Intent.ACTION_USER_BACKGROUND);
19040                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
19041                            | Intent.FLAG_RECEIVER_FOREGROUND);
19042                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
19043                    broadcastIntentLocked(null, null, intent,
19044                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
19045                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
19046                }
19047            }
19048            if (newUserId >= 0) {
19049                // Send USER_FOREGROUND broadcast to all profiles of the incoming user
19050                List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
19051                int count = profiles.size();
19052                for (int i = 0; i < count; i++) {
19053                    int profileUserId = profiles.get(i).id;
19054                    intent = new Intent(Intent.ACTION_USER_FOREGROUND);
19055                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
19056                            | Intent.FLAG_RECEIVER_FOREGROUND);
19057                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
19058                    broadcastIntentLocked(null, null, intent,
19059                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
19060                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
19061                }
19062                intent = new Intent(Intent.ACTION_USER_SWITCHED);
19063                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
19064                        | Intent.FLAG_RECEIVER_FOREGROUND);
19065                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
19066                broadcastIntentLocked(null, null, intent,
19067                        null, null, 0, null, null,
19068                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
19069                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
19070            }
19071        } finally {
19072            Binder.restoreCallingIdentity(ident);
19073        }
19074    }
19075
19076    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
19077            final int newUserId) {
19078        final int N = mUserSwitchObservers.beginBroadcast();
19079        if (N > 0) {
19080            final IRemoteCallback callback = new IRemoteCallback.Stub() {
19081                int mCount = 0;
19082                @Override
19083                public void sendResult(Bundle data) throws RemoteException {
19084                    synchronized (ActivityManagerService.this) {
19085                        if (mCurUserSwitchCallback == this) {
19086                            mCount++;
19087                            if (mCount == N) {
19088                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
19089                            }
19090                        }
19091                    }
19092                }
19093            };
19094            synchronized (this) {
19095                uss.switching = true;
19096                mCurUserSwitchCallback = callback;
19097            }
19098            for (int i=0; i<N; i++) {
19099                try {
19100                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
19101                            newUserId, callback);
19102                } catch (RemoteException e) {
19103                }
19104            }
19105        } else {
19106            synchronized (this) {
19107                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
19108            }
19109        }
19110        mUserSwitchObservers.finishBroadcast();
19111    }
19112
19113    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
19114        synchronized (this) {
19115            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
19116            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
19117        }
19118    }
19119
19120    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
19121        mCurUserSwitchCallback = null;
19122        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
19123        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
19124                oldUserId, newUserId, uss));
19125    }
19126
19127    void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) {
19128        synchronized (this) {
19129            if (foreground) {
19130                moveUserToForeground(uss, oldUserId, newUserId);
19131            }
19132        }
19133
19134        completeSwitchAndInitalize(uss, newUserId, true, false);
19135    }
19136
19137    void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) {
19138        boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss);
19139        if (homeInFront) {
19140            startHomeActivityLocked(newUserId);
19141        } else {
19142            mStackSupervisor.resumeTopActivitiesLocked();
19143        }
19144        EventLogTags.writeAmSwitchUser(newUserId);
19145        getUserManagerLocked().userForeground(newUserId);
19146        sendUserSwitchBroadcastsLocked(oldUserId, newUserId);
19147    }
19148
19149    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
19150        completeSwitchAndInitalize(uss, newUserId, false, true);
19151    }
19152
19153    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
19154            boolean clearInitializing, boolean clearSwitching) {
19155        boolean unfrozen = false;
19156        synchronized (this) {
19157            if (clearInitializing) {
19158                uss.initializing = false;
19159                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
19160            }
19161            if (clearSwitching) {
19162                uss.switching = false;
19163            }
19164            if (!uss.switching && !uss.initializing) {
19165                mWindowManager.stopFreezingScreen();
19166                unfrozen = true;
19167            }
19168        }
19169        if (unfrozen) {
19170            final int N = mUserSwitchObservers.beginBroadcast();
19171            for (int i=0; i<N; i++) {
19172                try {
19173                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
19174                } catch (RemoteException e) {
19175                }
19176            }
19177            mUserSwitchObservers.finishBroadcast();
19178        }
19179        stopGuestUserIfBackground();
19180    }
19181
19182    /**
19183     * Stops the guest user if it has gone to the background.
19184     */
19185    private void stopGuestUserIfBackground() {
19186        synchronized (this) {
19187            final int num = mUserLru.size();
19188            for (int i = 0; i < num; i++) {
19189                Integer oldUserId = mUserLru.get(i);
19190                UserStartedState oldUss = mStartedUsers.get(oldUserId);
19191                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId
19192                        || oldUss.mState == UserStartedState.STATE_STOPPING
19193                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
19194                    continue;
19195                }
19196                UserInfo userInfo = mUserManager.getUserInfo(oldUserId);
19197                if (userInfo.isGuest()) {
19198                    // This is a user to be stopped.
19199                    stopUserLocked(oldUserId, null);
19200                    break;
19201                }
19202            }
19203        }
19204    }
19205
19206    void scheduleStartProfilesLocked() {
19207        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
19208            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
19209                    DateUtils.SECOND_IN_MILLIS);
19210        }
19211    }
19212
19213    void startProfilesLocked() {
19214        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
19215        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
19216                mCurrentUserId, false /* enabledOnly */);
19217        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
19218        for (UserInfo user : profiles) {
19219            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
19220                    && user.id != mCurrentUserId) {
19221                toStart.add(user);
19222            }
19223        }
19224        final int n = toStart.size();
19225        int i = 0;
19226        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
19227            startUserInBackground(toStart.get(i).id);
19228        }
19229        if (i < n) {
19230            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
19231        }
19232    }
19233
19234    void finishUserBoot(UserStartedState uss) {
19235        synchronized (this) {
19236            if (uss.mState == UserStartedState.STATE_BOOTING
19237                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
19238                uss.mState = UserStartedState.STATE_RUNNING;
19239                final int userId = uss.mHandle.getIdentifier();
19240                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
19241                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
19242                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
19243                broadcastIntentLocked(null, null, intent,
19244                        null, null, 0, null, null,
19245                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
19246                        true, false, MY_PID, Process.SYSTEM_UID, userId);
19247            }
19248        }
19249    }
19250
19251    void finishUserSwitch(UserStartedState uss) {
19252        synchronized (this) {
19253            finishUserBoot(uss);
19254
19255            startProfilesLocked();
19256
19257            int num = mUserLru.size();
19258            int i = 0;
19259            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
19260                Integer oldUserId = mUserLru.get(i);
19261                UserStartedState oldUss = mStartedUsers.get(oldUserId);
19262                if (oldUss == null) {
19263                    // Shouldn't happen, but be sane if it does.
19264                    mUserLru.remove(i);
19265                    num--;
19266                    continue;
19267                }
19268                if (oldUss.mState == UserStartedState.STATE_STOPPING
19269                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
19270                    // This user is already stopping, doesn't count.
19271                    num--;
19272                    i++;
19273                    continue;
19274                }
19275                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
19276                    // Owner and current can't be stopped, but count as running.
19277                    i++;
19278                    continue;
19279                }
19280                // This is a user to be stopped.
19281                stopUserLocked(oldUserId, null);
19282                num--;
19283                i++;
19284            }
19285        }
19286    }
19287
19288    @Override
19289    public int stopUser(final int userId, final IStopUserCallback callback) {
19290        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
19291                != PackageManager.PERMISSION_GRANTED) {
19292            String msg = "Permission Denial: switchUser() from pid="
19293                    + Binder.getCallingPid()
19294                    + ", uid=" + Binder.getCallingUid()
19295                    + " requires " + INTERACT_ACROSS_USERS_FULL;
19296            Slog.w(TAG, msg);
19297            throw new SecurityException(msg);
19298        }
19299        if (userId <= 0) {
19300            throw new IllegalArgumentException("Can't stop primary user " + userId);
19301        }
19302        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
19303        synchronized (this) {
19304            return stopUserLocked(userId, callback);
19305        }
19306    }
19307
19308    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
19309        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
19310        if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) {
19311            return ActivityManager.USER_OP_IS_CURRENT;
19312        }
19313
19314        final UserStartedState uss = mStartedUsers.get(userId);
19315        if (uss == null) {
19316            // User is not started, nothing to do...  but we do need to
19317            // callback if requested.
19318            if (callback != null) {
19319                mHandler.post(new Runnable() {
19320                    @Override
19321                    public void run() {
19322                        try {
19323                            callback.userStopped(userId);
19324                        } catch (RemoteException e) {
19325                        }
19326                    }
19327                });
19328            }
19329            return ActivityManager.USER_OP_SUCCESS;
19330        }
19331
19332        if (callback != null) {
19333            uss.mStopCallbacks.add(callback);
19334        }
19335
19336        if (uss.mState != UserStartedState.STATE_STOPPING
19337                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
19338            uss.mState = UserStartedState.STATE_STOPPING;
19339            updateStartedUserArrayLocked();
19340
19341            long ident = Binder.clearCallingIdentity();
19342            try {
19343                // We are going to broadcast ACTION_USER_STOPPING and then
19344                // once that is done send a final ACTION_SHUTDOWN and then
19345                // stop the user.
19346                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
19347                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19348                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
19349                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
19350                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
19351                // This is the result receiver for the final shutdown broadcast.
19352                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
19353                    @Override
19354                    public void performReceive(Intent intent, int resultCode, String data,
19355                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
19356                        finishUserStop(uss);
19357                    }
19358                };
19359                // This is the result receiver for the initial stopping broadcast.
19360                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
19361                    @Override
19362                    public void performReceive(Intent intent, int resultCode, String data,
19363                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
19364                        // On to the next.
19365                        synchronized (ActivityManagerService.this) {
19366                            if (uss.mState != UserStartedState.STATE_STOPPING) {
19367                                // Whoops, we are being started back up.  Abort, abort!
19368                                return;
19369                            }
19370                            uss.mState = UserStartedState.STATE_SHUTDOWN;
19371                        }
19372                        mBatteryStatsService.noteEvent(
19373                                BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
19374                                Integer.toString(userId), userId);
19375                        mSystemServiceManager.stopUser(userId);
19376                        broadcastIntentLocked(null, null, shutdownIntent,
19377                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
19378                                true, false, MY_PID, Process.SYSTEM_UID, userId);
19379                    }
19380                };
19381                // Kick things off.
19382                broadcastIntentLocked(null, null, stoppingIntent,
19383                        null, stoppingReceiver, 0, null, null,
19384                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
19385                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
19386            } finally {
19387                Binder.restoreCallingIdentity(ident);
19388            }
19389        }
19390
19391        return ActivityManager.USER_OP_SUCCESS;
19392    }
19393
19394    void finishUserStop(UserStartedState uss) {
19395        final int userId = uss.mHandle.getIdentifier();
19396        boolean stopped;
19397        ArrayList<IStopUserCallback> callbacks;
19398        synchronized (this) {
19399            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
19400            if (mStartedUsers.get(userId) != uss) {
19401                stopped = false;
19402            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
19403                stopped = false;
19404            } else {
19405                stopped = true;
19406                // User can no longer run.
19407                mStartedUsers.remove(userId);
19408                mUserLru.remove(Integer.valueOf(userId));
19409                updateStartedUserArrayLocked();
19410
19411                // Clean up all state and processes associated with the user.
19412                // Kill all the processes for the user.
19413                forceStopUserLocked(userId, "finish user");
19414            }
19415
19416            // Explicitly remove the old information in mRecentTasks.
19417            removeRecentTasksForUserLocked(userId);
19418        }
19419
19420        for (int i=0; i<callbacks.size(); i++) {
19421            try {
19422                if (stopped) callbacks.get(i).userStopped(userId);
19423                else callbacks.get(i).userStopAborted(userId);
19424            } catch (RemoteException e) {
19425            }
19426        }
19427
19428        if (stopped) {
19429            mSystemServiceManager.cleanupUser(userId);
19430            synchronized (this) {
19431                mStackSupervisor.removeUserLocked(userId);
19432            }
19433        }
19434    }
19435
19436    @Override
19437    public UserInfo getCurrentUser() {
19438        if ((checkCallingPermission(INTERACT_ACROSS_USERS)
19439                != PackageManager.PERMISSION_GRANTED) && (
19440                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
19441                != PackageManager.PERMISSION_GRANTED)) {
19442            String msg = "Permission Denial: getCurrentUser() from pid="
19443                    + Binder.getCallingPid()
19444                    + ", uid=" + Binder.getCallingUid()
19445                    + " requires " + INTERACT_ACROSS_USERS;
19446            Slog.w(TAG, msg);
19447            throw new SecurityException(msg);
19448        }
19449        synchronized (this) {
19450            int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
19451            return getUserManagerLocked().getUserInfo(userId);
19452        }
19453    }
19454
19455    int getCurrentUserIdLocked() {
19456        return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
19457    }
19458
19459    @Override
19460    public boolean isUserRunning(int userId, boolean orStopped) {
19461        if (checkCallingPermission(INTERACT_ACROSS_USERS)
19462                != PackageManager.PERMISSION_GRANTED) {
19463            String msg = "Permission Denial: isUserRunning() from pid="
19464                    + Binder.getCallingPid()
19465                    + ", uid=" + Binder.getCallingUid()
19466                    + " requires " + INTERACT_ACROSS_USERS;
19467            Slog.w(TAG, msg);
19468            throw new SecurityException(msg);
19469        }
19470        synchronized (this) {
19471            return isUserRunningLocked(userId, orStopped);
19472        }
19473    }
19474
19475    boolean isUserRunningLocked(int userId, boolean orStopped) {
19476        UserStartedState state = mStartedUsers.get(userId);
19477        if (state == null) {
19478            return false;
19479        }
19480        if (orStopped) {
19481            return true;
19482        }
19483        return state.mState != UserStartedState.STATE_STOPPING
19484                && state.mState != UserStartedState.STATE_SHUTDOWN;
19485    }
19486
19487    @Override
19488    public int[] getRunningUserIds() {
19489        if (checkCallingPermission(INTERACT_ACROSS_USERS)
19490                != PackageManager.PERMISSION_GRANTED) {
19491            String msg = "Permission Denial: isUserRunning() from pid="
19492                    + Binder.getCallingPid()
19493                    + ", uid=" + Binder.getCallingUid()
19494                    + " requires " + INTERACT_ACROSS_USERS;
19495            Slog.w(TAG, msg);
19496            throw new SecurityException(msg);
19497        }
19498        synchronized (this) {
19499            return mStartedUserArray;
19500        }
19501    }
19502
19503    private void updateStartedUserArrayLocked() {
19504        int num = 0;
19505        for (int i=0; i<mStartedUsers.size();  i++) {
19506            UserStartedState uss = mStartedUsers.valueAt(i);
19507            // This list does not include stopping users.
19508            if (uss.mState != UserStartedState.STATE_STOPPING
19509                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
19510                num++;
19511            }
19512        }
19513        mStartedUserArray = new int[num];
19514        num = 0;
19515        for (int i=0; i<mStartedUsers.size();  i++) {
19516            UserStartedState uss = mStartedUsers.valueAt(i);
19517            if (uss.mState != UserStartedState.STATE_STOPPING
19518                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
19519                mStartedUserArray[num] = mStartedUsers.keyAt(i);
19520                num++;
19521            }
19522        }
19523    }
19524
19525    @Override
19526    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
19527        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
19528                != PackageManager.PERMISSION_GRANTED) {
19529            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
19530                    + Binder.getCallingPid()
19531                    + ", uid=" + Binder.getCallingUid()
19532                    + " requires " + INTERACT_ACROSS_USERS_FULL;
19533            Slog.w(TAG, msg);
19534            throw new SecurityException(msg);
19535        }
19536
19537        mUserSwitchObservers.register(observer);
19538    }
19539
19540    @Override
19541    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
19542        mUserSwitchObservers.unregister(observer);
19543    }
19544
19545    private boolean userExists(int userId) {
19546        if (userId == 0) {
19547            return true;
19548        }
19549        UserManagerService ums = getUserManagerLocked();
19550        return ums != null ? (ums.getUserInfo(userId) != null) : false;
19551    }
19552
19553    int[] getUsersLocked() {
19554        UserManagerService ums = getUserManagerLocked();
19555        return ums != null ? ums.getUserIds() : new int[] { 0 };
19556    }
19557
19558    UserManagerService getUserManagerLocked() {
19559        if (mUserManager == null) {
19560            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
19561            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
19562        }
19563        return mUserManager;
19564    }
19565
19566    private int applyUserId(int uid, int userId) {
19567        return UserHandle.getUid(userId, uid);
19568    }
19569
19570    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
19571        if (info == null) return null;
19572        ApplicationInfo newInfo = new ApplicationInfo(info);
19573        newInfo.uid = applyUserId(info.uid, userId);
19574        newInfo.dataDir = USER_DATA_DIR + userId + "/"
19575                + info.packageName;
19576        return newInfo;
19577    }
19578
19579    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
19580        if (aInfo == null
19581                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
19582            return aInfo;
19583        }
19584
19585        ActivityInfo info = new ActivityInfo(aInfo);
19586        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
19587        return info;
19588    }
19589
19590    private final class LocalService extends ActivityManagerInternal {
19591        @Override
19592        public void onWakefulnessChanged(int wakefulness) {
19593            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
19594        }
19595
19596        @Override
19597        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
19598                String processName, String abiOverride, int uid, Runnable crashHandler) {
19599            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
19600                    processName, abiOverride, uid, crashHandler);
19601        }
19602    }
19603
19604    /**
19605     * An implementation of IAppTask, that allows an app to manage its own tasks via
19606     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
19607     * only the process that calls getAppTasks() can call the AppTask methods.
19608     */
19609    class AppTaskImpl extends IAppTask.Stub {
19610        private int mTaskId;
19611        private int mCallingUid;
19612
19613        public AppTaskImpl(int taskId, int callingUid) {
19614            mTaskId = taskId;
19615            mCallingUid = callingUid;
19616        }
19617
19618        private void checkCaller() {
19619            if (mCallingUid != Binder.getCallingUid()) {
19620                throw new SecurityException("Caller " + mCallingUid
19621                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
19622            }
19623        }
19624
19625        @Override
19626        public void finishAndRemoveTask() {
19627            checkCaller();
19628
19629            synchronized (ActivityManagerService.this) {
19630                long origId = Binder.clearCallingIdentity();
19631                try {
19632                    if (!removeTaskByIdLocked(mTaskId, false)) {
19633                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19634                    }
19635                } finally {
19636                    Binder.restoreCallingIdentity(origId);
19637                }
19638            }
19639        }
19640
19641        @Override
19642        public ActivityManager.RecentTaskInfo getTaskInfo() {
19643            checkCaller();
19644
19645            synchronized (ActivityManagerService.this) {
19646                long origId = Binder.clearCallingIdentity();
19647                try {
19648                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
19649                    if (tr == null) {
19650                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19651                    }
19652                    return createRecentTaskInfoFromTaskRecord(tr);
19653                } finally {
19654                    Binder.restoreCallingIdentity(origId);
19655                }
19656            }
19657        }
19658
19659        @Override
19660        public void moveToFront() {
19661            checkCaller();
19662            // Will bring task to front if it already has a root activity.
19663            startActivityFromRecentsInner(mTaskId, null);
19664        }
19665
19666        @Override
19667        public int startActivity(IBinder whoThread, String callingPackage,
19668                Intent intent, String resolvedType, Bundle options) {
19669            checkCaller();
19670
19671            int callingUser = UserHandle.getCallingUserId();
19672            TaskRecord tr;
19673            IApplicationThread appThread;
19674            synchronized (ActivityManagerService.this) {
19675                tr = recentTaskForIdLocked(mTaskId);
19676                if (tr == null) {
19677                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19678                }
19679                appThread = ApplicationThreadNative.asInterface(whoThread);
19680                if (appThread == null) {
19681                    throw new IllegalArgumentException("Bad app thread " + appThread);
19682                }
19683            }
19684            return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent,
19685                    resolvedType, null, null, null, null, 0, 0, null, null,
19686                    null, options, callingUser, null, tr);
19687        }
19688
19689        @Override
19690        public void setExcludeFromRecents(boolean exclude) {
19691            checkCaller();
19692
19693            synchronized (ActivityManagerService.this) {
19694                long origId = Binder.clearCallingIdentity();
19695                try {
19696                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
19697                    if (tr == null) {
19698                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19699                    }
19700                    Intent intent = tr.getBaseIntent();
19701                    if (exclude) {
19702                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
19703                    } else {
19704                        intent.setFlags(intent.getFlags()
19705                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
19706                    }
19707                } finally {
19708                    Binder.restoreCallingIdentity(origId);
19709                }
19710            }
19711        }
19712    }
19713}
19714