ActivityManagerService.java revision 465e996776d916d8d1b62c539142827bd96a42bc
1/*
2 * Copyright (C) 2006-2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.am;
18
19import static android.Manifest.permission.INTERACT_ACROSS_USERS;
20import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
21import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
22import static android.content.pm.PackageManager.PERMISSION_GRANTED;
23import static com.android.internal.util.XmlUtils.readBooleanAttribute;
24import static com.android.internal.util.XmlUtils.readIntAttribute;
25import static com.android.internal.util.XmlUtils.readLongAttribute;
26import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
27import static com.android.internal.util.XmlUtils.writeIntAttribute;
28import static com.android.internal.util.XmlUtils.writeLongAttribute;
29import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST;
30import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
31import static org.xmlpull.v1.XmlPullParser.START_TAG;
32import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
33
34import android.Manifest;
35import android.app.AppOpsManager;
36import android.app.ApplicationThreadNative;
37import android.app.IActivityContainer;
38import android.app.IActivityContainerCallback;
39import android.app.IAppTask;
40import android.app.ProfilerInfo;
41import android.app.admin.DevicePolicyManager;
42import android.app.usage.UsageEvents;
43import android.app.usage.UsageStatsManagerInternal;
44import android.appwidget.AppWidgetManager;
45import android.content.res.Resources;
46import android.graphics.Bitmap;
47import android.graphics.Point;
48import android.graphics.Rect;
49import android.os.BatteryStats;
50import android.os.PersistableBundle;
51import android.os.storage.IMountService;
52import android.os.storage.StorageManager;
53import android.service.voice.IVoiceInteractionSession;
54import android.util.ArrayMap;
55import android.util.ArraySet;
56import android.util.SparseIntArray;
57
58import com.android.internal.R;
59import com.android.internal.annotations.GuardedBy;
60import com.android.internal.app.IAppOpsService;
61import com.android.internal.app.IVoiceInteractor;
62import com.android.internal.app.ProcessMap;
63import com.android.internal.app.ProcessStats;
64import com.android.internal.os.BackgroundThread;
65import com.android.internal.os.BatteryStatsImpl;
66import com.android.internal.os.ProcessCpuTracker;
67import com.android.internal.os.TransferPipe;
68import com.android.internal.os.Zygote;
69import com.android.internal.util.FastPrintWriter;
70import com.android.internal.util.FastXmlSerializer;
71import com.android.internal.util.MemInfoReader;
72import com.android.internal.util.Preconditions;
73import com.android.server.AppOpsService;
74import com.android.server.AttributeCache;
75import com.android.server.IntentResolver;
76import com.android.server.LocalServices;
77import com.android.server.ServiceThread;
78import com.android.server.SystemService;
79import com.android.server.SystemServiceManager;
80import com.android.server.Watchdog;
81import com.android.server.am.ActivityStack.ActivityState;
82import com.android.server.firewall.IntentFirewall;
83import com.android.server.pm.Installer;
84import com.android.server.pm.UserManagerService;
85import com.android.server.statusbar.StatusBarManagerInternal;
86import com.android.server.wm.AppTransition;
87import com.android.server.wm.WindowManagerService;
88import com.google.android.collect.Lists;
89import com.google.android.collect.Maps;
90
91import libcore.io.IoUtils;
92
93import org.xmlpull.v1.XmlPullParser;
94import org.xmlpull.v1.XmlPullParserException;
95import org.xmlpull.v1.XmlSerializer;
96
97import android.app.Activity;
98import android.app.ActivityManager;
99import android.app.ActivityManager.RunningTaskInfo;
100import android.app.ActivityManager.StackInfo;
101import android.app.ActivityManagerInternal;
102import android.app.ActivityManagerNative;
103import android.app.ActivityOptions;
104import android.app.ActivityThread;
105import android.app.AlertDialog;
106import android.app.AppGlobals;
107import android.app.ApplicationErrorReport;
108import android.app.Dialog;
109import android.app.IActivityController;
110import android.app.IApplicationThread;
111import android.app.IInstrumentationWatcher;
112import android.app.INotificationManager;
113import android.app.IProcessObserver;
114import android.app.IServiceConnection;
115import android.app.IStopUserCallback;
116import android.app.IUiAutomationConnection;
117import android.app.IUserSwitchObserver;
118import android.app.Instrumentation;
119import android.app.Notification;
120import android.app.NotificationManager;
121import android.app.PendingIntent;
122import android.app.backup.IBackupManager;
123import android.content.ActivityNotFoundException;
124import android.content.BroadcastReceiver;
125import android.content.ClipData;
126import android.content.ComponentCallbacks2;
127import android.content.ComponentName;
128import android.content.ContentProvider;
129import android.content.ContentResolver;
130import android.content.Context;
131import android.content.DialogInterface;
132import android.content.IContentProvider;
133import android.content.IIntentReceiver;
134import android.content.IIntentSender;
135import android.content.Intent;
136import android.content.IntentFilter;
137import android.content.IntentSender;
138import android.content.pm.ActivityInfo;
139import android.content.pm.ApplicationInfo;
140import android.content.pm.ConfigurationInfo;
141import android.content.pm.IPackageDataObserver;
142import android.content.pm.IPackageManager;
143import android.content.pm.InstrumentationInfo;
144import android.content.pm.PackageInfo;
145import android.content.pm.PackageManager;
146import android.content.pm.ParceledListSlice;
147import android.content.pm.UserInfo;
148import android.content.pm.PackageManager.NameNotFoundException;
149import android.content.pm.PathPermission;
150import android.content.pm.ProviderInfo;
151import android.content.pm.ResolveInfo;
152import android.content.pm.ServiceInfo;
153import android.content.res.CompatibilityInfo;
154import android.content.res.Configuration;
155import android.net.Proxy;
156import android.net.ProxyInfo;
157import android.net.Uri;
158import android.os.Binder;
159import android.os.Build;
160import android.os.Bundle;
161import android.os.Debug;
162import android.os.DropBoxManager;
163import android.os.Environment;
164import android.os.FactoryTest;
165import android.os.FileObserver;
166import android.os.FileUtils;
167import android.os.Handler;
168import android.os.IBinder;
169import android.os.IPermissionController;
170import android.os.IRemoteCallback;
171import android.os.IUserManager;
172import android.os.Looper;
173import android.os.Message;
174import android.os.Parcel;
175import android.os.ParcelFileDescriptor;
176import android.os.Process;
177import android.os.RemoteCallbackList;
178import android.os.RemoteException;
179import android.os.SELinux;
180import android.os.ServiceManager;
181import android.os.StrictMode;
182import android.os.SystemClock;
183import android.os.SystemProperties;
184import android.os.UpdateLock;
185import android.os.UserHandle;
186import android.os.UserManager;
187import android.provider.Settings;
188import android.text.format.DateUtils;
189import android.text.format.Time;
190import android.util.AtomicFile;
191import android.util.EventLog;
192import android.util.Log;
193import android.util.Pair;
194import android.util.PrintWriterPrinter;
195import android.util.Slog;
196import android.util.SparseArray;
197import android.util.TimeUtils;
198import android.util.Xml;
199import android.view.Gravity;
200import android.view.LayoutInflater;
201import android.view.View;
202import android.view.WindowManager;
203
204import dalvik.system.VMRuntime;
205
206import java.io.BufferedInputStream;
207import java.io.BufferedOutputStream;
208import java.io.DataInputStream;
209import java.io.DataOutputStream;
210import java.io.File;
211import java.io.FileDescriptor;
212import java.io.FileInputStream;
213import java.io.FileNotFoundException;
214import java.io.FileOutputStream;
215import java.io.IOException;
216import java.io.InputStreamReader;
217import java.io.PrintWriter;
218import java.io.StringWriter;
219import java.lang.ref.WeakReference;
220import java.util.ArrayList;
221import java.util.Arrays;
222import java.util.Collections;
223import java.util.Comparator;
224import java.util.HashMap;
225import java.util.HashSet;
226import java.util.Iterator;
227import java.util.List;
228import java.util.Locale;
229import java.util.Map;
230import java.util.Set;
231import java.util.concurrent.atomic.AtomicBoolean;
232import java.util.concurrent.atomic.AtomicLong;
233
234public final class ActivityManagerService extends ActivityManagerNative
235        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
236
237    private static final String USER_DATA_DIR = "/data/user/";
238    // File that stores last updated system version and called preboot receivers
239    static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat";
240
241    static final String TAG = "ActivityManager";
242    static final String TAG_MU = "ActivityManagerServiceMU";
243    static final boolean DEBUG = false;
244    static final boolean localLOGV = DEBUG;
245    static final boolean DEBUG_BACKUP = localLOGV || false;
246    static final boolean DEBUG_BROADCAST = localLOGV || false;
247    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
248    static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
249    static final boolean DEBUG_CLEANUP = localLOGV || false;
250    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
251    static final boolean DEBUG_FOCUS = false;
252    static final boolean DEBUG_IMMERSIVE = localLOGV || false;
253    static final boolean DEBUG_MU = localLOGV || false;
254    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
255    static final boolean DEBUG_LRU = localLOGV || false;
256    static final boolean DEBUG_PAUSE = localLOGV || false;
257    static final boolean DEBUG_POWER = localLOGV || false;
258    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
259    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
260    static final boolean DEBUG_PROCESSES = localLOGV || false;
261    static final boolean DEBUG_PROVIDER = localLOGV || false;
262    static final boolean DEBUG_RESULTS = localLOGV || false;
263    static final boolean DEBUG_SERVICE = localLOGV || false;
264    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
265    static final boolean DEBUG_STACK = localLOGV || false;
266    static final boolean DEBUG_SWITCH = localLOGV || false;
267    static final boolean DEBUG_TASKS = localLOGV || false;
268    static final boolean DEBUG_THUMBNAILS = localLOGV || false;
269    static final boolean DEBUG_TRANSITION = localLOGV || false;
270    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
271    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
272    static final boolean DEBUG_VISBILITY = localLOGV || false;
273    static final boolean DEBUG_PSS = localLOGV || false;
274    static final boolean DEBUG_LOCKSCREEN = localLOGV || false;
275    static final boolean DEBUG_RECENTS = localLOGV || false;
276    static final boolean VALIDATE_TOKENS = false;
277    static final boolean SHOW_ACTIVITY_START_TIME = true;
278
279    // Control over CPU and battery monitoring.
280    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
281    static final boolean MONITOR_CPU_USAGE = true;
282    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
283    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
284    static final boolean MONITOR_THREAD_CPU_USAGE = false;
285
286    // The flags that are set for all calls we make to the package manager.
287    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
288
289    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
290
291    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
292
293    // Maximum number recent bitmaps to keep in memory.
294    static final int MAX_RECENT_BITMAPS = 5;
295
296    // Amount of time after a call to stopAppSwitches() during which we will
297    // prevent further untrusted switches from happening.
298    static final long APP_SWITCH_DELAY_TIME = 5*1000;
299
300    // How long we wait for a launched process to attach to the activity manager
301    // before we decide it's never going to come up for real.
302    static final int PROC_START_TIMEOUT = 10*1000;
303
304    // How long we wait for a launched process to attach to the activity manager
305    // before we decide it's never going to come up for real, when the process was
306    // started with a wrapper for instrumentation (such as Valgrind) because it
307    // could take much longer than usual.
308    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
309
310    // How long to wait after going idle before forcing apps to GC.
311    static final int GC_TIMEOUT = 5*1000;
312
313    // The minimum amount of time between successive GC requests for a process.
314    static final int GC_MIN_INTERVAL = 60*1000;
315
316    // The minimum amount of time between successive PSS requests for a process.
317    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
318
319    // The minimum amount of time between successive PSS requests for a process
320    // when the request is due to the memory state being lowered.
321    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
322
323    // The rate at which we check for apps using excessive power -- 15 mins.
324    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
325
326    // The minimum sample duration we will allow before deciding we have
327    // enough data on wake locks to start killing things.
328    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
329
330    // The minimum sample duration we will allow before deciding we have
331    // enough data on CPU usage to start killing things.
332    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
333
334    // How long we allow a receiver to run before giving up on it.
335    static final int BROADCAST_FG_TIMEOUT = 10*1000;
336    static final int BROADCAST_BG_TIMEOUT = 60*1000;
337
338    // How long we wait until we timeout on key dispatching.
339    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
340
341    // How long we wait until we timeout on key dispatching during instrumentation.
342    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
343
344    // Amount of time we wait for observers to handle a user switch before
345    // giving up on them and unfreezing the screen.
346    static final int USER_SWITCH_TIMEOUT = 2*1000;
347
348    // Maximum number of users we allow to be running at a time.
349    static final int MAX_RUNNING_USERS = 3;
350
351    // How long to wait in getAssistContextExtras for the activity and foreground services
352    // to respond with the result.
353    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
354
355    // Maximum number of persisted Uri grants a package is allowed
356    static final int MAX_PERSISTED_URI_GRANTS = 128;
357
358    static final int MY_PID = Process.myPid();
359
360    static final String[] EMPTY_STRING_ARRAY = new String[0];
361
362    // How many bytes to write into the dropbox log before truncating
363    static final int DROPBOX_MAX_SIZE = 256 * 1024;
364
365    // Access modes for handleIncomingUser.
366    static final int ALLOW_NON_FULL = 0;
367    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
368    static final int ALLOW_FULL_ONLY = 2;
369
370    static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000;
371
372    /** All system services */
373    SystemServiceManager mSystemServiceManager;
374
375    private Installer mInstaller;
376
377    /** Run all ActivityStacks through this */
378    ActivityStackSupervisor mStackSupervisor;
379
380    public IntentFirewall mIntentFirewall;
381
382    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
383    // default actuion automatically.  Important for devices without direct input
384    // devices.
385    private boolean mShowDialogs = true;
386
387    BroadcastQueue mFgBroadcastQueue;
388    BroadcastQueue mBgBroadcastQueue;
389    // Convenient for easy iteration over the queues. Foreground is first
390    // so that dispatch of foreground broadcasts gets precedence.
391    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
392
393    BroadcastQueue broadcastQueueForIntent(Intent intent) {
394        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
395        if (DEBUG_BACKGROUND_BROADCAST) {
396            Slog.i(TAG, "Broadcast intent " + intent + " on "
397                    + (isFg ? "foreground" : "background")
398                    + " queue");
399        }
400        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
401    }
402
403    BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
404        for (BroadcastQueue queue : mBroadcastQueues) {
405            BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
406            if (r != null) {
407                return r;
408            }
409        }
410        return null;
411    }
412
413    /**
414     * Activity we have told the window manager to have key focus.
415     */
416    ActivityRecord mFocusedActivity = null;
417
418    /**
419     * List of intents that were used to start the most recent tasks.
420     */
421    ArrayList<TaskRecord> mRecentTasks;
422    ArrayList<TaskRecord> mTmpRecents = new ArrayList<TaskRecord>();
423
424    /**
425     * For addAppTask: cached of the last activity component that was added.
426     */
427    ComponentName mLastAddedTaskComponent;
428
429    /**
430     * For addAppTask: cached of the last activity uid that was added.
431     */
432    int mLastAddedTaskUid;
433
434    /**
435     * For addAppTask: cached of the last ActivityInfo that was added.
436     */
437    ActivityInfo mLastAddedTaskActivity;
438
439    public class PendingAssistExtras extends Binder implements Runnable {
440        public final ActivityRecord activity;
441        public final Bundle extras;
442        public final Intent intent;
443        public final String hint;
444        public final int userHandle;
445        public boolean haveResult = false;
446        public Bundle result = null;
447        public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
448                String _hint, int _userHandle) {
449            activity = _activity;
450            extras = _extras;
451            intent = _intent;
452            hint = _hint;
453            userHandle = _userHandle;
454        }
455        @Override
456        public void run() {
457            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
458            synchronized (this) {
459                haveResult = true;
460                notifyAll();
461            }
462        }
463    }
464
465    final ArrayList<PendingAssistExtras> mPendingAssistExtras
466            = new ArrayList<PendingAssistExtras>();
467
468    /**
469     * Process management.
470     */
471    final ProcessList mProcessList = new ProcessList();
472
473    /**
474     * All of the applications we currently have running organized by name.
475     * The keys are strings of the application package name (as
476     * returned by the package manager), and the keys are ApplicationRecord
477     * objects.
478     */
479    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
480
481    /**
482     * Tracking long-term execution of processes to look for abuse and other
483     * bad app behavior.
484     */
485    final ProcessStatsService mProcessStats;
486
487    /**
488     * The currently running isolated processes.
489     */
490    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
491
492    /**
493     * Counter for assigning isolated process uids, to avoid frequently reusing the
494     * same ones.
495     */
496    int mNextIsolatedProcessUid = 0;
497
498    /**
499     * The currently running heavy-weight process, if any.
500     */
501    ProcessRecord mHeavyWeightProcess = null;
502
503    /**
504     * The last time that various processes have crashed.
505     */
506    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
507
508    /**
509     * Information about a process that is currently marked as bad.
510     */
511    static final class BadProcessInfo {
512        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
513            this.time = time;
514            this.shortMsg = shortMsg;
515            this.longMsg = longMsg;
516            this.stack = stack;
517        }
518
519        final long time;
520        final String shortMsg;
521        final String longMsg;
522        final String stack;
523    }
524
525    /**
526     * Set of applications that we consider to be bad, and will reject
527     * incoming broadcasts from (which the user has no control over).
528     * Processes are added to this set when they have crashed twice within
529     * a minimum amount of time; they are removed from it when they are
530     * later restarted (hopefully due to some user action).  The value is the
531     * time it was added to the list.
532     */
533    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
534
535    /**
536     * All of the processes we currently have running organized by pid.
537     * The keys are the pid running the application.
538     *
539     * <p>NOTE: This object is protected by its own lock, NOT the global
540     * activity manager lock!
541     */
542    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
543
544    /**
545     * All of the processes that have been forced to be foreground.  The key
546     * is the pid of the caller who requested it (we hold a death
547     * link on it).
548     */
549    abstract class ForegroundToken implements IBinder.DeathRecipient {
550        int pid;
551        IBinder token;
552    }
553    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
554
555    /**
556     * List of records for processes that someone had tried to start before the
557     * system was ready.  We don't start them at that point, but ensure they
558     * are started by the time booting is complete.
559     */
560    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
561
562    /**
563     * List of persistent applications that are in the process
564     * of being started.
565     */
566    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
567
568    /**
569     * Processes that are being forcibly torn down.
570     */
571    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
572
573    /**
574     * List of running applications, sorted by recent usage.
575     * The first entry in the list is the least recently used.
576     */
577    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
578
579    /**
580     * Where in mLruProcesses that the processes hosting activities start.
581     */
582    int mLruProcessActivityStart = 0;
583
584    /**
585     * Where in mLruProcesses that the processes hosting services start.
586     * This is after (lower index) than mLruProcessesActivityStart.
587     */
588    int mLruProcessServiceStart = 0;
589
590    /**
591     * List of processes that should gc as soon as things are idle.
592     */
593    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
594
595    /**
596     * Processes we want to collect PSS data from.
597     */
598    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
599
600    /**
601     * Last time we requested PSS data of all processes.
602     */
603    long mLastFullPssTime = SystemClock.uptimeMillis();
604
605    /**
606     * If set, the next time we collect PSS data we should do a full collection
607     * with data from native processes and the kernel.
608     */
609    boolean mFullPssPending = false;
610
611    /**
612     * This is the process holding what we currently consider to be
613     * the "home" activity.
614     */
615    ProcessRecord mHomeProcess;
616
617    /**
618     * This is the process holding the activity the user last visited that
619     * is in a different process from the one they are currently in.
620     */
621    ProcessRecord mPreviousProcess;
622
623    /**
624     * The time at which the previous process was last visible.
625     */
626    long mPreviousProcessVisibleTime;
627
628    /**
629     * Which uses have been started, so are allowed to run code.
630     */
631    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
632
633    /**
634     * LRU list of history of current users.  Most recently current is at the end.
635     */
636    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
637
638    /**
639     * Constant array of the users that are currently started.
640     */
641    int[] mStartedUserArray = new int[] { 0 };
642
643    /**
644     * Registered observers of the user switching mechanics.
645     */
646    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
647            = new RemoteCallbackList<IUserSwitchObserver>();
648
649    /**
650     * Currently active user switch.
651     */
652    Object mCurUserSwitchCallback;
653
654    /**
655     * Packages that the user has asked to have run in screen size
656     * compatibility mode instead of filling the screen.
657     */
658    final CompatModePackages mCompatModePackages;
659
660    /**
661     * Set of IntentSenderRecord objects that are currently active.
662     */
663    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
664            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
665
666    /**
667     * Fingerprints (hashCode()) of stack traces that we've
668     * already logged DropBox entries for.  Guarded by itself.  If
669     * something (rogue user app) forces this over
670     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
671     */
672    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
673    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
674
675    /**
676     * Strict Mode background batched logging state.
677     *
678     * The string buffer is guarded by itself, and its lock is also
679     * used to determine if another batched write is already
680     * in-flight.
681     */
682    private final StringBuilder mStrictModeBuffer = new StringBuilder();
683
684    /**
685     * Keeps track of all IIntentReceivers that have been registered for
686     * broadcasts.  Hash keys are the receiver IBinder, hash value is
687     * a ReceiverList.
688     */
689    final HashMap<IBinder, ReceiverList> mRegisteredReceivers =
690            new HashMap<IBinder, ReceiverList>();
691
692    /**
693     * Resolver for broadcast intents to registered receivers.
694     * Holds BroadcastFilter (subclass of IntentFilter).
695     */
696    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
697            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
698        @Override
699        protected boolean allowFilterResult(
700                BroadcastFilter filter, List<BroadcastFilter> dest) {
701            IBinder target = filter.receiverList.receiver.asBinder();
702            for (int i=dest.size()-1; i>=0; i--) {
703                if (dest.get(i).receiverList.receiver.asBinder() == target) {
704                    return false;
705                }
706            }
707            return true;
708        }
709
710        @Override
711        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
712            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
713                    || userId == filter.owningUserId) {
714                return super.newResult(filter, match, userId);
715            }
716            return null;
717        }
718
719        @Override
720        protected BroadcastFilter[] newArray(int size) {
721            return new BroadcastFilter[size];
722        }
723
724        @Override
725        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
726            return packageName.equals(filter.packageName);
727        }
728    };
729
730    /**
731     * State of all active sticky broadcasts per user.  Keys are the action of the
732     * sticky Intent, values are an ArrayList of all broadcasted intents with
733     * that action (which should usually be one).  The SparseArray is keyed
734     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
735     * for stickies that are sent to all users.
736     */
737    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
738            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
739
740    final ActiveServices mServices;
741
742    /**
743     * Backup/restore process management
744     */
745    String mBackupAppName = null;
746    BackupRecord mBackupTarget = null;
747
748    final ProviderMap mProviderMap;
749
750    /**
751     * List of content providers who have clients waiting for them.  The
752     * application is currently being launched and the provider will be
753     * removed from this list once it is published.
754     */
755    final ArrayList<ContentProviderRecord> mLaunchingProviders
756            = new ArrayList<ContentProviderRecord>();
757
758    /**
759     * File storing persisted {@link #mGrantedUriPermissions}.
760     */
761    private final AtomicFile mGrantFile;
762
763    /** XML constants used in {@link #mGrantFile} */
764    private static final String TAG_URI_GRANTS = "uri-grants";
765    private static final String TAG_URI_GRANT = "uri-grant";
766    private static final String ATTR_USER_HANDLE = "userHandle";
767    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
768    private static final String ATTR_TARGET_USER_ID = "targetUserId";
769    private static final String ATTR_SOURCE_PKG = "sourcePkg";
770    private static final String ATTR_TARGET_PKG = "targetPkg";
771    private static final String ATTR_URI = "uri";
772    private static final String ATTR_MODE_FLAGS = "modeFlags";
773    private static final String ATTR_CREATED_TIME = "createdTime";
774    private static final String ATTR_PREFIX = "prefix";
775
776    /**
777     * Global set of specific {@link Uri} permissions that have been granted.
778     * This optimized lookup structure maps from {@link UriPermission#targetUid}
779     * to {@link UriPermission#uri} to {@link UriPermission}.
780     */
781    @GuardedBy("this")
782    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
783            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
784
785    public static class GrantUri {
786        public final int sourceUserId;
787        public final Uri uri;
788        public boolean prefix;
789
790        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
791            this.sourceUserId = sourceUserId;
792            this.uri = uri;
793            this.prefix = prefix;
794        }
795
796        @Override
797        public int hashCode() {
798            return toString().hashCode();
799        }
800
801        @Override
802        public boolean equals(Object o) {
803            if (o instanceof GrantUri) {
804                GrantUri other = (GrantUri) o;
805                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
806                        && prefix == other.prefix;
807            }
808            return false;
809        }
810
811        @Override
812        public String toString() {
813            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
814            if (prefix) result += " [prefix]";
815            return result;
816        }
817
818        public String toSafeString() {
819            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
820            if (prefix) result += " [prefix]";
821            return result;
822        }
823
824        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
825            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
826                    ContentProvider.getUriWithoutUserId(uri), false);
827        }
828    }
829
830    CoreSettingsObserver mCoreSettingsObserver;
831
832    /**
833     * Thread-local storage used to carry caller permissions over through
834     * indirect content-provider access.
835     */
836    private class Identity {
837        public int pid;
838        public int uid;
839
840        Identity(int _pid, int _uid) {
841            pid = _pid;
842            uid = _uid;
843        }
844    }
845
846    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
847
848    /**
849     * All information we have collected about the runtime performance of
850     * any user id that can impact battery performance.
851     */
852    final BatteryStatsService mBatteryStatsService;
853
854    /**
855     * Information about component usage
856     */
857    UsageStatsManagerInternal mUsageStatsService;
858
859    /**
860     * Information about and control over application operations
861     */
862    final AppOpsService mAppOpsService;
863
864    /**
865     * Save recent tasks information across reboots.
866     */
867    final TaskPersister mTaskPersister;
868
869    /**
870     * Current configuration information.  HistoryRecord objects are given
871     * a reference to this object to indicate which configuration they are
872     * currently running in, so this object must be kept immutable.
873     */
874    Configuration mConfiguration = new Configuration();
875
876    /**
877     * Current sequencing integer of the configuration, for skipping old
878     * configurations.
879     */
880    int mConfigurationSeq = 0;
881
882    /**
883     * Hardware-reported OpenGLES version.
884     */
885    final int GL_ES_VERSION;
886
887    /**
888     * List of initialization arguments to pass to all processes when binding applications to them.
889     * For example, references to the commonly used services.
890     */
891    HashMap<String, IBinder> mAppBindArgs;
892
893    /**
894     * Temporary to avoid allocations.  Protected by main lock.
895     */
896    final StringBuilder mStringBuilder = new StringBuilder(256);
897
898    /**
899     * Used to control how we initialize the service.
900     */
901    ComponentName mTopComponent;
902    String mTopAction = Intent.ACTION_MAIN;
903    String mTopData;
904    boolean mProcessesReady = false;
905    boolean mSystemReady = false;
906    boolean mBooting = false;
907    boolean mCallFinishBooting = false;
908    boolean mBootAnimationComplete = false;
909    boolean mWaitingUpdate = false;
910    boolean mDidUpdate = false;
911    boolean mOnBattery = false;
912    boolean mLaunchWarningShown = false;
913
914    Context mContext;
915
916    int mFactoryTest;
917
918    boolean mCheckedForSetup;
919
920    /**
921     * The time at which we will allow normal application switches again,
922     * after a call to {@link #stopAppSwitches()}.
923     */
924    long mAppSwitchesAllowedTime;
925
926    /**
927     * This is set to true after the first switch after mAppSwitchesAllowedTime
928     * is set; any switches after that will clear the time.
929     */
930    boolean mDidAppSwitch;
931
932    /**
933     * Last time (in realtime) at which we checked for power usage.
934     */
935    long mLastPowerCheckRealtime;
936
937    /**
938     * Last time (in uptime) at which we checked for power usage.
939     */
940    long mLastPowerCheckUptime;
941
942    /**
943     * Set while we are wanting to sleep, to prevent any
944     * activities from being started/resumed.
945     */
946    private boolean mSleeping = false;
947
948    /**
949     * Set while we are running a voice interaction.  This overrides
950     * sleeping while it is active.
951     */
952    private boolean mRunningVoice = false;
953
954    /**
955     * State of external calls telling us if the device is asleep.
956     */
957    private boolean mWentToSleep = false;
958
959    static final int LOCK_SCREEN_HIDDEN = 0;
960    static final int LOCK_SCREEN_LEAVING = 1;
961    static final int LOCK_SCREEN_SHOWN = 2;
962    /**
963     * State of external call telling us if the lock screen is shown.
964     */
965    int mLockScreenShown = LOCK_SCREEN_HIDDEN;
966
967    /**
968     * Set if we are shutting down the system, similar to sleeping.
969     */
970    boolean mShuttingDown = false;
971
972    /**
973     * Current sequence id for oom_adj computation traversal.
974     */
975    int mAdjSeq = 0;
976
977    /**
978     * Current sequence id for process LRU updating.
979     */
980    int mLruSeq = 0;
981
982    /**
983     * Keep track of the non-cached/empty process we last found, to help
984     * determine how to distribute cached/empty processes next time.
985     */
986    int mNumNonCachedProcs = 0;
987
988    /**
989     * Keep track of the number of cached hidden procs, to balance oom adj
990     * distribution between those and empty procs.
991     */
992    int mNumCachedHiddenProcs = 0;
993
994    /**
995     * Keep track of the number of service processes we last found, to
996     * determine on the next iteration which should be B services.
997     */
998    int mNumServiceProcs = 0;
999    int mNewNumAServiceProcs = 0;
1000    int mNewNumServiceProcs = 0;
1001
1002    /**
1003     * Allow the current computed overall memory level of the system to go down?
1004     * This is set to false when we are killing processes for reasons other than
1005     * memory management, so that the now smaller process list will not be taken as
1006     * an indication that memory is tighter.
1007     */
1008    boolean mAllowLowerMemLevel = false;
1009
1010    /**
1011     * The last computed memory level, for holding when we are in a state that
1012     * processes are going away for other reasons.
1013     */
1014    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1015
1016    /**
1017     * The last total number of process we have, to determine if changes actually look
1018     * like a shrinking number of process due to lower RAM.
1019     */
1020    int mLastNumProcesses;
1021
1022    /**
1023     * The uptime of the last time we performed idle maintenance.
1024     */
1025    long mLastIdleTime = SystemClock.uptimeMillis();
1026
1027    /**
1028     * Total time spent with RAM that has been added in the past since the last idle time.
1029     */
1030    long mLowRamTimeSinceLastIdle = 0;
1031
1032    /**
1033     * If RAM is currently low, when that horrible situation started.
1034     */
1035    long mLowRamStartTime = 0;
1036
1037    /**
1038     * For reporting to battery stats the current top application.
1039     */
1040    private String mCurResumedPackage = null;
1041    private int mCurResumedUid = -1;
1042
1043    /**
1044     * For reporting to battery stats the apps currently running foreground
1045     * service.  The ProcessMap is package/uid tuples; each of these contain
1046     * an array of the currently foreground processes.
1047     */
1048    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1049            = new ProcessMap<ArrayList<ProcessRecord>>();
1050
1051    /**
1052     * This is set if we had to do a delayed dexopt of an app before launching
1053     * it, to increase the ANR timeouts in that case.
1054     */
1055    boolean mDidDexOpt;
1056
1057    /**
1058     * Set if the systemServer made a call to enterSafeMode.
1059     */
1060    boolean mSafeMode;
1061
1062    String mDebugApp = null;
1063    boolean mWaitForDebugger = false;
1064    boolean mDebugTransient = false;
1065    String mOrigDebugApp = null;
1066    boolean mOrigWaitForDebugger = false;
1067    boolean mAlwaysFinishActivities = false;
1068    IActivityController mController = null;
1069    String mProfileApp = null;
1070    ProcessRecord mProfileProc = null;
1071    String mProfileFile;
1072    ParcelFileDescriptor mProfileFd;
1073    int mSamplingInterval = 0;
1074    boolean mAutoStopProfiler = false;
1075    int mProfileType = 0;
1076    String mOpenGlTraceApp = null;
1077
1078    static class ProcessChangeItem {
1079        static final int CHANGE_ACTIVITIES = 1<<0;
1080        static final int CHANGE_PROCESS_STATE = 1<<1;
1081        int changes;
1082        int uid;
1083        int pid;
1084        int processState;
1085        boolean foregroundActivities;
1086    }
1087
1088    final RemoteCallbackList<IProcessObserver> mProcessObservers
1089            = new RemoteCallbackList<IProcessObserver>();
1090    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1091
1092    final ArrayList<ProcessChangeItem> mPendingProcessChanges
1093            = new ArrayList<ProcessChangeItem>();
1094    final ArrayList<ProcessChangeItem> mAvailProcessChanges
1095            = new ArrayList<ProcessChangeItem>();
1096
1097    /**
1098     * Runtime CPU use collection thread.  This object's lock is used to
1099     * perform synchronization with the thread (notifying it to run).
1100     */
1101    final Thread mProcessCpuThread;
1102
1103    /**
1104     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1105     * Must acquire this object's lock when accessing it.
1106     * NOTE: this lock will be held while doing long operations (trawling
1107     * through all processes in /proc), so it should never be acquired by
1108     * any critical paths such as when holding the main activity manager lock.
1109     */
1110    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1111            MONITOR_THREAD_CPU_USAGE);
1112    final AtomicLong mLastCpuTime = new AtomicLong(0);
1113    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1114
1115    long mLastWriteTime = 0;
1116
1117    /**
1118     * Used to retain an update lock when the foreground activity is in
1119     * immersive mode.
1120     */
1121    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1122
1123    /**
1124     * Set to true after the system has finished booting.
1125     */
1126    boolean mBooted = false;
1127
1128    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1129    int mProcessLimitOverride = -1;
1130
1131    WindowManagerService mWindowManager;
1132
1133    final ActivityThread mSystemThread;
1134
1135    // Holds the current foreground user's id
1136    int mCurrentUserId = 0;
1137    // Holds the target user's id during a user switch
1138    int mTargetUserId = UserHandle.USER_NULL;
1139    // If there are multiple profiles for the current user, their ids are here
1140    // Currently only the primary user can have managed profiles
1141    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1142
1143    /**
1144     * Mapping from each known user ID to the profile group ID it is associated with.
1145     */
1146    SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray();
1147
1148    private UserManagerService mUserManager;
1149
1150    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1151        final ProcessRecord mApp;
1152        final int mPid;
1153        final IApplicationThread mAppThread;
1154
1155        AppDeathRecipient(ProcessRecord app, int pid,
1156                IApplicationThread thread) {
1157            if (localLOGV) Slog.v(
1158                TAG, "New death recipient " + this
1159                + " for thread " + thread.asBinder());
1160            mApp = app;
1161            mPid = pid;
1162            mAppThread = thread;
1163        }
1164
1165        @Override
1166        public void binderDied() {
1167            if (localLOGV) Slog.v(
1168                TAG, "Death received in " + this
1169                + " for thread " + mAppThread.asBinder());
1170            synchronized(ActivityManagerService.this) {
1171                appDiedLocked(mApp, mPid, mAppThread);
1172            }
1173        }
1174    }
1175
1176    static final int SHOW_ERROR_MSG = 1;
1177    static final int SHOW_NOT_RESPONDING_MSG = 2;
1178    static final int SHOW_FACTORY_ERROR_MSG = 3;
1179    static final int UPDATE_CONFIGURATION_MSG = 4;
1180    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1181    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1182    static final int SERVICE_TIMEOUT_MSG = 12;
1183    static final int UPDATE_TIME_ZONE = 13;
1184    static final int SHOW_UID_ERROR_MSG = 14;
1185    static final int SHOW_FINGERPRINT_ERROR_MSG = 15;
1186    static final int PROC_START_TIMEOUT_MSG = 20;
1187    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1188    static final int KILL_APPLICATION_MSG = 22;
1189    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1190    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1191    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1192    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1193    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1194    static final int CLEAR_DNS_CACHE_MSG = 28;
1195    static final int UPDATE_HTTP_PROXY_MSG = 29;
1196    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1197    static final int DISPATCH_PROCESSES_CHANGED = 31;
1198    static final int DISPATCH_PROCESS_DIED = 32;
1199    static final int REPORT_MEM_USAGE_MSG = 33;
1200    static final int REPORT_USER_SWITCH_MSG = 34;
1201    static final int CONTINUE_USER_SWITCH_MSG = 35;
1202    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1203    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1204    static final int PERSIST_URI_GRANTS_MSG = 38;
1205    static final int REQUEST_ALL_PSS_MSG = 39;
1206    static final int START_PROFILES_MSG = 40;
1207    static final int UPDATE_TIME = 41;
1208    static final int SYSTEM_USER_START_MSG = 42;
1209    static final int SYSTEM_USER_CURRENT_MSG = 43;
1210    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1211    static final int FINISH_BOOTING_MSG = 45;
1212    static final int START_USER_SWITCH_MSG = 46;
1213    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1214    static final int DISMISS_DIALOG_MSG = 48;
1215
1216    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1217    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1218    static final int FIRST_COMPAT_MODE_MSG = 300;
1219    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1220
1221    CompatModeDialog mCompatModeDialog;
1222    long mLastMemUsageReportTime = 0;
1223
1224    /**
1225     * Flag whether the current user is a "monkey", i.e. whether
1226     * the UI is driven by a UI automation tool.
1227     */
1228    private boolean mUserIsMonkey;
1229
1230    /** Flag whether the device has a Recents UI */
1231    boolean mHasRecents;
1232
1233    /** The dimensions of the thumbnails in the Recents UI. */
1234    int mThumbnailWidth;
1235    int mThumbnailHeight;
1236
1237    final ServiceThread mHandlerThread;
1238    final MainHandler mHandler;
1239
1240    final class MainHandler extends Handler {
1241        public MainHandler(Looper looper) {
1242            super(looper, null, true);
1243        }
1244
1245        @Override
1246        public void handleMessage(Message msg) {
1247            switch (msg.what) {
1248            case SHOW_ERROR_MSG: {
1249                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1250                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1251                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1252                synchronized (ActivityManagerService.this) {
1253                    ProcessRecord proc = (ProcessRecord)data.get("app");
1254                    AppErrorResult res = (AppErrorResult) data.get("result");
1255                    if (proc != null && proc.crashDialog != null) {
1256                        Slog.e(TAG, "App already has crash dialog: " + proc);
1257                        if (res != null) {
1258                            res.set(0);
1259                        }
1260                        return;
1261                    }
1262                    boolean isBackground = (UserHandle.getAppId(proc.uid)
1263                            >= Process.FIRST_APPLICATION_UID
1264                            && proc.pid != MY_PID);
1265                    for (int userId : mCurrentProfileIds) {
1266                        isBackground &= (proc.userId != userId);
1267                    }
1268                    if (isBackground && !showBackground) {
1269                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1270                        if (res != null) {
1271                            res.set(0);
1272                        }
1273                        return;
1274                    }
1275                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1276                        Dialog d = new AppErrorDialog(mContext,
1277                                ActivityManagerService.this, res, proc);
1278                        d.show();
1279                        proc.crashDialog = d;
1280                    } else {
1281                        // The device is asleep, so just pretend that the user
1282                        // saw a crash dialog and hit "force quit".
1283                        if (res != null) {
1284                            res.set(0);
1285                        }
1286                    }
1287                }
1288
1289                ensureBootCompleted();
1290            } break;
1291            case SHOW_NOT_RESPONDING_MSG: {
1292                synchronized (ActivityManagerService.this) {
1293                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1294                    ProcessRecord proc = (ProcessRecord)data.get("app");
1295                    if (proc != null && proc.anrDialog != null) {
1296                        Slog.e(TAG, "App already has anr dialog: " + proc);
1297                        return;
1298                    }
1299
1300                    Intent intent = new Intent("android.intent.action.ANR");
1301                    if (!mProcessesReady) {
1302                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1303                                | Intent.FLAG_RECEIVER_FOREGROUND);
1304                    }
1305                    broadcastIntentLocked(null, null, intent,
1306                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1307                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1308
1309                    if (mShowDialogs) {
1310                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1311                                mContext, proc, (ActivityRecord)data.get("activity"),
1312                                msg.arg1 != 0);
1313                        d.show();
1314                        proc.anrDialog = d;
1315                    } else {
1316                        // Just kill the app if there is no dialog to be shown.
1317                        killAppAtUsersRequest(proc, null);
1318                    }
1319                }
1320
1321                ensureBootCompleted();
1322            } break;
1323            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1324                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1325                synchronized (ActivityManagerService.this) {
1326                    ProcessRecord proc = (ProcessRecord) data.get("app");
1327                    if (proc == null) {
1328                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1329                        break;
1330                    }
1331                    if (proc.crashDialog != null) {
1332                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1333                        return;
1334                    }
1335                    AppErrorResult res = (AppErrorResult) data.get("result");
1336                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1337                        Dialog d = new StrictModeViolationDialog(mContext,
1338                                ActivityManagerService.this, res, proc);
1339                        d.show();
1340                        proc.crashDialog = d;
1341                    } else {
1342                        // The device is asleep, so just pretend that the user
1343                        // saw a crash dialog and hit "force quit".
1344                        res.set(0);
1345                    }
1346                }
1347                ensureBootCompleted();
1348            } break;
1349            case SHOW_FACTORY_ERROR_MSG: {
1350                Dialog d = new FactoryErrorDialog(
1351                    mContext, msg.getData().getCharSequence("msg"));
1352                d.show();
1353                ensureBootCompleted();
1354            } break;
1355            case UPDATE_CONFIGURATION_MSG: {
1356                final ContentResolver resolver = mContext.getContentResolver();
1357                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1358            } break;
1359            case GC_BACKGROUND_PROCESSES_MSG: {
1360                synchronized (ActivityManagerService.this) {
1361                    performAppGcsIfAppropriateLocked();
1362                }
1363            } break;
1364            case WAIT_FOR_DEBUGGER_MSG: {
1365                synchronized (ActivityManagerService.this) {
1366                    ProcessRecord app = (ProcessRecord)msg.obj;
1367                    if (msg.arg1 != 0) {
1368                        if (!app.waitedForDebugger) {
1369                            Dialog d = new AppWaitingForDebuggerDialog(
1370                                    ActivityManagerService.this,
1371                                    mContext, app);
1372                            app.waitDialog = d;
1373                            app.waitedForDebugger = true;
1374                            d.show();
1375                        }
1376                    } else {
1377                        if (app.waitDialog != null) {
1378                            app.waitDialog.dismiss();
1379                            app.waitDialog = null;
1380                        }
1381                    }
1382                }
1383            } break;
1384            case SERVICE_TIMEOUT_MSG: {
1385                if (mDidDexOpt) {
1386                    mDidDexOpt = false;
1387                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1388                    nmsg.obj = msg.obj;
1389                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1390                    return;
1391                }
1392                mServices.serviceTimeout((ProcessRecord)msg.obj);
1393            } break;
1394            case UPDATE_TIME_ZONE: {
1395                synchronized (ActivityManagerService.this) {
1396                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1397                        ProcessRecord r = mLruProcesses.get(i);
1398                        if (r.thread != null) {
1399                            try {
1400                                r.thread.updateTimeZone();
1401                            } catch (RemoteException ex) {
1402                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1403                            }
1404                        }
1405                    }
1406                }
1407            } break;
1408            case CLEAR_DNS_CACHE_MSG: {
1409                synchronized (ActivityManagerService.this) {
1410                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1411                        ProcessRecord r = mLruProcesses.get(i);
1412                        if (r.thread != null) {
1413                            try {
1414                                r.thread.clearDnsCache();
1415                            } catch (RemoteException ex) {
1416                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1417                            }
1418                        }
1419                    }
1420                }
1421            } break;
1422            case UPDATE_HTTP_PROXY_MSG: {
1423                ProxyInfo proxy = (ProxyInfo)msg.obj;
1424                String host = "";
1425                String port = "";
1426                String exclList = "";
1427                Uri pacFileUrl = Uri.EMPTY;
1428                if (proxy != null) {
1429                    host = proxy.getHost();
1430                    port = Integer.toString(proxy.getPort());
1431                    exclList = proxy.getExclusionListAsString();
1432                    pacFileUrl = proxy.getPacFileUrl();
1433                }
1434                synchronized (ActivityManagerService.this) {
1435                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1436                        ProcessRecord r = mLruProcesses.get(i);
1437                        if (r.thread != null) {
1438                            try {
1439                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1440                            } catch (RemoteException ex) {
1441                                Slog.w(TAG, "Failed to update http proxy for: " +
1442                                        r.info.processName);
1443                            }
1444                        }
1445                    }
1446                }
1447            } break;
1448            case SHOW_UID_ERROR_MSG: {
1449                if (mShowDialogs) {
1450                    AlertDialog d = new BaseErrorDialog(mContext);
1451                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1452                    d.setCancelable(false);
1453                    d.setTitle(mContext.getText(R.string.android_system_label));
1454                    d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1455                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1456                            mHandler.obtainMessage(DISMISS_DIALOG_MSG, d));
1457                    d.show();
1458                }
1459            } break;
1460            case SHOW_FINGERPRINT_ERROR_MSG: {
1461                if (mShowDialogs) {
1462                    AlertDialog d = new BaseErrorDialog(mContext);
1463                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1464                    d.setCancelable(false);
1465                    d.setTitle(mContext.getText(R.string.android_system_label));
1466                    d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1467                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1468                            mHandler.obtainMessage(DISMISS_DIALOG_MSG, d));
1469                    d.show();
1470                }
1471            } break;
1472            case PROC_START_TIMEOUT_MSG: {
1473                if (mDidDexOpt) {
1474                    mDidDexOpt = false;
1475                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1476                    nmsg.obj = msg.obj;
1477                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1478                    return;
1479                }
1480                ProcessRecord app = (ProcessRecord)msg.obj;
1481                synchronized (ActivityManagerService.this) {
1482                    processStartTimedOutLocked(app);
1483                }
1484            } break;
1485            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1486                synchronized (ActivityManagerService.this) {
1487                    mStackSupervisor.doPendingActivityLaunchesLocked(true);
1488                }
1489            } break;
1490            case KILL_APPLICATION_MSG: {
1491                synchronized (ActivityManagerService.this) {
1492                    int appid = msg.arg1;
1493                    boolean restart = (msg.arg2 == 1);
1494                    Bundle bundle = (Bundle)msg.obj;
1495                    String pkg = bundle.getString("pkg");
1496                    String reason = bundle.getString("reason");
1497                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1498                            false, UserHandle.USER_ALL, reason);
1499                }
1500            } break;
1501            case FINALIZE_PENDING_INTENT_MSG: {
1502                ((PendingIntentRecord)msg.obj).completeFinalize();
1503            } break;
1504            case POST_HEAVY_NOTIFICATION_MSG: {
1505                INotificationManager inm = NotificationManager.getService();
1506                if (inm == null) {
1507                    return;
1508                }
1509
1510                ActivityRecord root = (ActivityRecord)msg.obj;
1511                ProcessRecord process = root.app;
1512                if (process == null) {
1513                    return;
1514                }
1515
1516                try {
1517                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1518                    String text = mContext.getString(R.string.heavy_weight_notification,
1519                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1520                    Notification notification = new Notification();
1521                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1522                    notification.when = 0;
1523                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1524                    notification.tickerText = text;
1525                    notification.defaults = 0; // please be quiet
1526                    notification.sound = null;
1527                    notification.vibrate = null;
1528                    notification.color = mContext.getResources().getColor(
1529                            com.android.internal.R.color.system_notification_accent_color);
1530                    notification.setLatestEventInfo(context, text,
1531                            mContext.getText(R.string.heavy_weight_notification_detail),
1532                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1533                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1534                                    new UserHandle(root.userId)));
1535
1536                    try {
1537                        int[] outId = new int[1];
1538                        inm.enqueueNotificationWithTag("android", "android", null,
1539                                R.string.heavy_weight_notification,
1540                                notification, outId, root.userId);
1541                    } catch (RuntimeException e) {
1542                        Slog.w(ActivityManagerService.TAG,
1543                                "Error showing notification for heavy-weight app", e);
1544                    } catch (RemoteException e) {
1545                    }
1546                } catch (NameNotFoundException e) {
1547                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1548                }
1549            } break;
1550            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1551                INotificationManager inm = NotificationManager.getService();
1552                if (inm == null) {
1553                    return;
1554                }
1555                try {
1556                    inm.cancelNotificationWithTag("android", null,
1557                            R.string.heavy_weight_notification,  msg.arg1);
1558                } catch (RuntimeException e) {
1559                    Slog.w(ActivityManagerService.TAG,
1560                            "Error canceling notification for service", e);
1561                } catch (RemoteException e) {
1562                }
1563            } break;
1564            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1565                synchronized (ActivityManagerService.this) {
1566                    checkExcessivePowerUsageLocked(true);
1567                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1568                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1569                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1570                }
1571            } break;
1572            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1573                synchronized (ActivityManagerService.this) {
1574                    ActivityRecord ar = (ActivityRecord)msg.obj;
1575                    if (mCompatModeDialog != null) {
1576                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1577                                ar.info.applicationInfo.packageName)) {
1578                            return;
1579                        }
1580                        mCompatModeDialog.dismiss();
1581                        mCompatModeDialog = null;
1582                    }
1583                    if (ar != null && false) {
1584                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1585                                ar.packageName)) {
1586                            int mode = mCompatModePackages.computeCompatModeLocked(
1587                                    ar.info.applicationInfo);
1588                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1589                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1590                                mCompatModeDialog = new CompatModeDialog(
1591                                        ActivityManagerService.this, mContext,
1592                                        ar.info.applicationInfo);
1593                                mCompatModeDialog.show();
1594                            }
1595                        }
1596                    }
1597                }
1598                break;
1599            }
1600            case DISPATCH_PROCESSES_CHANGED: {
1601                dispatchProcessesChanged();
1602                break;
1603            }
1604            case DISPATCH_PROCESS_DIED: {
1605                final int pid = msg.arg1;
1606                final int uid = msg.arg2;
1607                dispatchProcessDied(pid, uid);
1608                break;
1609            }
1610            case REPORT_MEM_USAGE_MSG: {
1611                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1612                Thread thread = new Thread() {
1613                    @Override public void run() {
1614                        reportMemUsage(memInfos);
1615                    }
1616                };
1617                thread.start();
1618                break;
1619            }
1620            case START_USER_SWITCH_MSG: {
1621                showUserSwitchDialog(msg.arg1, (String) msg.obj);
1622                break;
1623            }
1624            case REPORT_USER_SWITCH_MSG: {
1625                dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1626                break;
1627            }
1628            case CONTINUE_USER_SWITCH_MSG: {
1629                continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1630                break;
1631            }
1632            case USER_SWITCH_TIMEOUT_MSG: {
1633                timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1634                break;
1635            }
1636            case IMMERSIVE_MODE_LOCK_MSG: {
1637                final boolean nextState = (msg.arg1 != 0);
1638                if (mUpdateLock.isHeld() != nextState) {
1639                    if (DEBUG_IMMERSIVE) {
1640                        final ActivityRecord r = (ActivityRecord) msg.obj;
1641                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1642                    }
1643                    if (nextState) {
1644                        mUpdateLock.acquire();
1645                    } else {
1646                        mUpdateLock.release();
1647                    }
1648                }
1649                break;
1650            }
1651            case PERSIST_URI_GRANTS_MSG: {
1652                writeGrantedUriPermissions();
1653                break;
1654            }
1655            case REQUEST_ALL_PSS_MSG: {
1656                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1657                break;
1658            }
1659            case START_PROFILES_MSG: {
1660                synchronized (ActivityManagerService.this) {
1661                    startProfilesLocked();
1662                }
1663                break;
1664            }
1665            case UPDATE_TIME: {
1666                synchronized (ActivityManagerService.this) {
1667                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1668                        ProcessRecord r = mLruProcesses.get(i);
1669                        if (r.thread != null) {
1670                            try {
1671                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1672                            } catch (RemoteException ex) {
1673                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1674                            }
1675                        }
1676                    }
1677                }
1678                break;
1679            }
1680            case SYSTEM_USER_START_MSG: {
1681                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1682                        Integer.toString(msg.arg1), msg.arg1);
1683                mSystemServiceManager.startUser(msg.arg1);
1684                break;
1685            }
1686            case SYSTEM_USER_CURRENT_MSG: {
1687                mBatteryStatsService.noteEvent(
1688                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1689                        Integer.toString(msg.arg2), msg.arg2);
1690                mBatteryStatsService.noteEvent(
1691                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1692                        Integer.toString(msg.arg1), msg.arg1);
1693                mSystemServiceManager.switchUser(msg.arg1);
1694                break;
1695            }
1696            case ENTER_ANIMATION_COMPLETE_MSG: {
1697                synchronized (ActivityManagerService.this) {
1698                    ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj);
1699                    if (r != null && r.app != null && r.app.thread != null) {
1700                        try {
1701                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1702                        } catch (RemoteException e) {
1703                        }
1704                    }
1705                }
1706                break;
1707            }
1708            case FINISH_BOOTING_MSG: {
1709                if (msg.arg1 != 0) {
1710                    finishBooting();
1711                }
1712                if (msg.arg2 != 0) {
1713                    enableScreenAfterBoot();
1714                }
1715                break;
1716            }
1717            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
1718                try {
1719                    Locale l = (Locale) msg.obj;
1720                    IBinder service = ServiceManager.getService("mount");
1721                    IMountService mountService = IMountService.Stub.asInterface(service);
1722                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
1723                    mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
1724                } catch (RemoteException e) {
1725                    Log.e(TAG, "Error storing locale for decryption UI", e);
1726                }
1727                break;
1728            }
1729            case DISMISS_DIALOG_MSG: {
1730                final Dialog d = (Dialog) msg.obj;
1731                d.dismiss();
1732                break;
1733            }
1734            }
1735        }
1736    };
1737
1738    static final int COLLECT_PSS_BG_MSG = 1;
1739
1740    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1741        @Override
1742        public void handleMessage(Message msg) {
1743            switch (msg.what) {
1744            case COLLECT_PSS_BG_MSG: {
1745                long start = SystemClock.uptimeMillis();
1746                MemInfoReader memInfo = null;
1747                synchronized (ActivityManagerService.this) {
1748                    if (mFullPssPending) {
1749                        mFullPssPending = false;
1750                        memInfo = new MemInfoReader();
1751                    }
1752                }
1753                if (memInfo != null) {
1754                    updateCpuStatsNow();
1755                    long nativeTotalPss = 0;
1756                    synchronized (mProcessCpuTracker) {
1757                        final int N = mProcessCpuTracker.countStats();
1758                        for (int j=0; j<N; j++) {
1759                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
1760                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
1761                                // This is definitely an application process; skip it.
1762                                continue;
1763                            }
1764                            synchronized (mPidsSelfLocked) {
1765                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
1766                                    // This is one of our own processes; skip it.
1767                                    continue;
1768                                }
1769                            }
1770                            nativeTotalPss += Debug.getPss(st.pid, null);
1771                        }
1772                    }
1773                    memInfo.readMemInfo();
1774                    synchronized (ActivityManagerService.this) {
1775                        if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in "
1776                                + (SystemClock.uptimeMillis()-start) + "ms");
1777                        mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
1778                                memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
1779                                memInfo.getKernelUsedSizeKb(), nativeTotalPss);
1780                    }
1781                }
1782
1783                int i = 0;
1784                int num = 0;
1785                long[] tmp = new long[1];
1786                do {
1787                    ProcessRecord proc;
1788                    int procState;
1789                    int pid;
1790                    synchronized (ActivityManagerService.this) {
1791                        if (i >= mPendingPssProcesses.size()) {
1792                            if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1793                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1794                            mPendingPssProcesses.clear();
1795                            return;
1796                        }
1797                        proc = mPendingPssProcesses.get(i);
1798                        procState = proc.pssProcState;
1799                        if (proc.thread != null && procState == proc.setProcState) {
1800                            pid = proc.pid;
1801                        } else {
1802                            proc = null;
1803                            pid = 0;
1804                        }
1805                        i++;
1806                    }
1807                    if (proc != null) {
1808                        long pss = Debug.getPss(pid, tmp);
1809                        synchronized (ActivityManagerService.this) {
1810                            if (proc.thread != null && proc.setProcState == procState
1811                                    && proc.pid == pid) {
1812                                num++;
1813                                proc.lastPssTime = SystemClock.uptimeMillis();
1814                                proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
1815                                if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
1816                                        + ": " + pss + " lastPss=" + proc.lastPss
1817                                        + " state=" + ProcessList.makeProcStateString(procState));
1818                                if (proc.initialIdlePss == 0) {
1819                                    proc.initialIdlePss = pss;
1820                                }
1821                                proc.lastPss = pss;
1822                                if (procState >= ActivityManager.PROCESS_STATE_HOME) {
1823                                    proc.lastCachedPss = pss;
1824                                }
1825                            }
1826                        }
1827                    }
1828                } while (true);
1829            }
1830            }
1831        }
1832    };
1833
1834    public void setSystemProcess() {
1835        try {
1836            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
1837            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
1838            ServiceManager.addService("meminfo", new MemBinder(this));
1839            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
1840            ServiceManager.addService("dbinfo", new DbBinder(this));
1841            if (MONITOR_CPU_USAGE) {
1842                ServiceManager.addService("cpuinfo", new CpuBinder(this));
1843            }
1844            ServiceManager.addService("permission", new PermissionController(this));
1845
1846            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
1847                    "android", STOCK_PM_FLAGS);
1848            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
1849
1850            synchronized (this) {
1851                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
1852                app.persistent = true;
1853                app.pid = MY_PID;
1854                app.maxAdj = ProcessList.SYSTEM_ADJ;
1855                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
1856                mProcessNames.put(app.processName, app.uid, app);
1857                synchronized (mPidsSelfLocked) {
1858                    mPidsSelfLocked.put(app.pid, app);
1859                }
1860                updateLruProcessLocked(app, false, null);
1861                updateOomAdjLocked();
1862            }
1863        } catch (PackageManager.NameNotFoundException e) {
1864            throw new RuntimeException(
1865                    "Unable to find android system package", e);
1866        }
1867    }
1868
1869    public void setWindowManager(WindowManagerService wm) {
1870        mWindowManager = wm;
1871        mStackSupervisor.setWindowManager(wm);
1872    }
1873
1874    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
1875        mUsageStatsService = usageStatsManager;
1876    }
1877
1878    public void startObservingNativeCrashes() {
1879        final NativeCrashListener ncl = new NativeCrashListener(this);
1880        ncl.start();
1881    }
1882
1883    public IAppOpsService getAppOpsService() {
1884        return mAppOpsService;
1885    }
1886
1887    static class MemBinder extends Binder {
1888        ActivityManagerService mActivityManagerService;
1889        MemBinder(ActivityManagerService activityManagerService) {
1890            mActivityManagerService = activityManagerService;
1891        }
1892
1893        @Override
1894        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1895            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1896                    != PackageManager.PERMISSION_GRANTED) {
1897                pw.println("Permission Denial: can't dump meminfo from from pid="
1898                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1899                        + " without permission " + android.Manifest.permission.DUMP);
1900                return;
1901            }
1902
1903            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
1904        }
1905    }
1906
1907    static class GraphicsBinder extends Binder {
1908        ActivityManagerService mActivityManagerService;
1909        GraphicsBinder(ActivityManagerService activityManagerService) {
1910            mActivityManagerService = activityManagerService;
1911        }
1912
1913        @Override
1914        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1915            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1916                    != PackageManager.PERMISSION_GRANTED) {
1917                pw.println("Permission Denial: can't dump gfxinfo from from pid="
1918                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1919                        + " without permission " + android.Manifest.permission.DUMP);
1920                return;
1921            }
1922
1923            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
1924        }
1925    }
1926
1927    static class DbBinder extends Binder {
1928        ActivityManagerService mActivityManagerService;
1929        DbBinder(ActivityManagerService activityManagerService) {
1930            mActivityManagerService = activityManagerService;
1931        }
1932
1933        @Override
1934        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1935            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1936                    != PackageManager.PERMISSION_GRANTED) {
1937                pw.println("Permission Denial: can't dump dbinfo from from pid="
1938                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1939                        + " without permission " + android.Manifest.permission.DUMP);
1940                return;
1941            }
1942
1943            mActivityManagerService.dumpDbInfo(fd, pw, args);
1944        }
1945    }
1946
1947    static class CpuBinder extends Binder {
1948        ActivityManagerService mActivityManagerService;
1949        CpuBinder(ActivityManagerService activityManagerService) {
1950            mActivityManagerService = activityManagerService;
1951        }
1952
1953        @Override
1954        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1955            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1956                    != PackageManager.PERMISSION_GRANTED) {
1957                pw.println("Permission Denial: can't dump cpuinfo from from pid="
1958                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1959                        + " without permission " + android.Manifest.permission.DUMP);
1960                return;
1961            }
1962
1963            synchronized (mActivityManagerService.mProcessCpuTracker) {
1964                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
1965                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
1966                        SystemClock.uptimeMillis()));
1967            }
1968        }
1969    }
1970
1971    public static final class Lifecycle extends SystemService {
1972        private final ActivityManagerService mService;
1973
1974        public Lifecycle(Context context) {
1975            super(context);
1976            mService = new ActivityManagerService(context);
1977        }
1978
1979        @Override
1980        public void onStart() {
1981            mService.start();
1982        }
1983
1984        public ActivityManagerService getService() {
1985            return mService;
1986        }
1987    }
1988
1989    // Note: This method is invoked on the main thread but may need to attach various
1990    // handlers to other threads.  So take care to be explicit about the looper.
1991    public ActivityManagerService(Context systemContext) {
1992        mContext = systemContext;
1993        mFactoryTest = FactoryTest.getMode();
1994        mSystemThread = ActivityThread.currentActivityThread();
1995
1996        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
1997
1998        mHandlerThread = new ServiceThread(TAG,
1999                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2000        mHandlerThread.start();
2001        mHandler = new MainHandler(mHandlerThread.getLooper());
2002
2003        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2004                "foreground", BROADCAST_FG_TIMEOUT, false);
2005        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2006                "background", BROADCAST_BG_TIMEOUT, true);
2007        mBroadcastQueues[0] = mFgBroadcastQueue;
2008        mBroadcastQueues[1] = mBgBroadcastQueue;
2009
2010        mServices = new ActiveServices(this);
2011        mProviderMap = new ProviderMap(this);
2012
2013        // TODO: Move creation of battery stats service outside of activity manager service.
2014        File dataDir = Environment.getDataDirectory();
2015        File systemDir = new File(dataDir, "system");
2016        systemDir.mkdirs();
2017        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2018        mBatteryStatsService.getActiveStatistics().readLocked();
2019        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2020        mOnBattery = DEBUG_POWER ? true
2021                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2022        mBatteryStatsService.getActiveStatistics().setCallback(this);
2023
2024        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2025
2026        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2027
2028        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2029
2030        // User 0 is the first and only user that runs at boot.
2031        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2032        mUserLru.add(Integer.valueOf(0));
2033        updateStartedUserArrayLocked();
2034
2035        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2036            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2037
2038        mConfiguration.setToDefaults();
2039        mConfiguration.setLocale(Locale.getDefault());
2040
2041        mConfigurationSeq = mConfiguration.seq = 1;
2042        mProcessCpuTracker.init();
2043
2044        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2045        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2046        mStackSupervisor = new ActivityStackSupervisor(this);
2047        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor);
2048
2049        mProcessCpuThread = new Thread("CpuTracker") {
2050            @Override
2051            public void run() {
2052                while (true) {
2053                    try {
2054                        try {
2055                            synchronized(this) {
2056                                final long now = SystemClock.uptimeMillis();
2057                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2058                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2059                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2060                                //        + ", write delay=" + nextWriteDelay);
2061                                if (nextWriteDelay < nextCpuDelay) {
2062                                    nextCpuDelay = nextWriteDelay;
2063                                }
2064                                if (nextCpuDelay > 0) {
2065                                    mProcessCpuMutexFree.set(true);
2066                                    this.wait(nextCpuDelay);
2067                                }
2068                            }
2069                        } catch (InterruptedException e) {
2070                        }
2071                        updateCpuStatsNow();
2072                    } catch (Exception e) {
2073                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2074                    }
2075                }
2076            }
2077        };
2078
2079        Watchdog.getInstance().addMonitor(this);
2080        Watchdog.getInstance().addThread(mHandler);
2081    }
2082
2083    public void setSystemServiceManager(SystemServiceManager mgr) {
2084        mSystemServiceManager = mgr;
2085    }
2086
2087    public void setInstaller(Installer installer) {
2088        mInstaller = installer;
2089    }
2090
2091    private void start() {
2092        Process.removeAllProcessGroups();
2093        mProcessCpuThread.start();
2094
2095        mBatteryStatsService.publish(mContext);
2096        mAppOpsService.publish(mContext);
2097        Slog.d("AppOps", "AppOpsService published");
2098        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2099    }
2100
2101    public void initPowerManagement() {
2102        mStackSupervisor.initPowerManagement();
2103        mBatteryStatsService.initPowerManagement();
2104    }
2105
2106    @Override
2107    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2108            throws RemoteException {
2109        if (code == SYSPROPS_TRANSACTION) {
2110            // We need to tell all apps about the system property change.
2111            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2112            synchronized(this) {
2113                final int NP = mProcessNames.getMap().size();
2114                for (int ip=0; ip<NP; ip++) {
2115                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2116                    final int NA = apps.size();
2117                    for (int ia=0; ia<NA; ia++) {
2118                        ProcessRecord app = apps.valueAt(ia);
2119                        if (app.thread != null) {
2120                            procs.add(app.thread.asBinder());
2121                        }
2122                    }
2123                }
2124            }
2125
2126            int N = procs.size();
2127            for (int i=0; i<N; i++) {
2128                Parcel data2 = Parcel.obtain();
2129                try {
2130                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2131                } catch (RemoteException e) {
2132                }
2133                data2.recycle();
2134            }
2135        }
2136        try {
2137            return super.onTransact(code, data, reply, flags);
2138        } catch (RuntimeException e) {
2139            // The activity manager only throws security exceptions, so let's
2140            // log all others.
2141            if (!(e instanceof SecurityException)) {
2142                Slog.wtf(TAG, "Activity Manager Crash", e);
2143            }
2144            throw e;
2145        }
2146    }
2147
2148    void updateCpuStats() {
2149        final long now = SystemClock.uptimeMillis();
2150        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2151            return;
2152        }
2153        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2154            synchronized (mProcessCpuThread) {
2155                mProcessCpuThread.notify();
2156            }
2157        }
2158    }
2159
2160    void updateCpuStatsNow() {
2161        synchronized (mProcessCpuTracker) {
2162            mProcessCpuMutexFree.set(false);
2163            final long now = SystemClock.uptimeMillis();
2164            boolean haveNewCpuStats = false;
2165
2166            if (MONITOR_CPU_USAGE &&
2167                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2168                mLastCpuTime.set(now);
2169                haveNewCpuStats = true;
2170                mProcessCpuTracker.update();
2171                //Slog.i(TAG, mProcessCpu.printCurrentState());
2172                //Slog.i(TAG, "Total CPU usage: "
2173                //        + mProcessCpu.getTotalCpuPercent() + "%");
2174
2175                // Slog the cpu usage if the property is set.
2176                if ("true".equals(SystemProperties.get("events.cpu"))) {
2177                    int user = mProcessCpuTracker.getLastUserTime();
2178                    int system = mProcessCpuTracker.getLastSystemTime();
2179                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2180                    int irq = mProcessCpuTracker.getLastIrqTime();
2181                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2182                    int idle = mProcessCpuTracker.getLastIdleTime();
2183
2184                    int total = user + system + iowait + irq + softIrq + idle;
2185                    if (total == 0) total = 1;
2186
2187                    EventLog.writeEvent(EventLogTags.CPU,
2188                            ((user+system+iowait+irq+softIrq) * 100) / total,
2189                            (user * 100) / total,
2190                            (system * 100) / total,
2191                            (iowait * 100) / total,
2192                            (irq * 100) / total,
2193                            (softIrq * 100) / total);
2194                }
2195            }
2196
2197            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2198            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2199            synchronized(bstats) {
2200                synchronized(mPidsSelfLocked) {
2201                    if (haveNewCpuStats) {
2202                        if (mOnBattery) {
2203                            int perc = bstats.startAddingCpuLocked();
2204                            int totalUTime = 0;
2205                            int totalSTime = 0;
2206                            final int N = mProcessCpuTracker.countStats();
2207                            for (int i=0; i<N; i++) {
2208                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2209                                if (!st.working) {
2210                                    continue;
2211                                }
2212                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2213                                int otherUTime = (st.rel_utime*perc)/100;
2214                                int otherSTime = (st.rel_stime*perc)/100;
2215                                totalUTime += otherUTime;
2216                                totalSTime += otherSTime;
2217                                if (pr != null) {
2218                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2219                                    if (ps == null || !ps.isActive()) {
2220                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2221                                                pr.info.uid, pr.processName);
2222                                    }
2223                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2224                                            st.rel_stime-otherSTime);
2225                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2226                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2227                                } else {
2228                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2229                                    if (ps == null || !ps.isActive()) {
2230                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2231                                                bstats.mapUid(st.uid), st.name);
2232                                    }
2233                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2234                                            st.rel_stime-otherSTime);
2235                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2236                                }
2237                            }
2238                            bstats.finishAddingCpuLocked(perc, totalUTime,
2239                                    totalSTime, cpuSpeedTimes);
2240                        }
2241                    }
2242                }
2243
2244                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2245                    mLastWriteTime = now;
2246                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2247                }
2248            }
2249        }
2250    }
2251
2252    @Override
2253    public void batteryNeedsCpuUpdate() {
2254        updateCpuStatsNow();
2255    }
2256
2257    @Override
2258    public void batteryPowerChanged(boolean onBattery) {
2259        // When plugging in, update the CPU stats first before changing
2260        // the plug state.
2261        updateCpuStatsNow();
2262        synchronized (this) {
2263            synchronized(mPidsSelfLocked) {
2264                mOnBattery = DEBUG_POWER ? true : onBattery;
2265            }
2266        }
2267    }
2268
2269    /**
2270     * Initialize the application bind args. These are passed to each
2271     * process when the bindApplication() IPC is sent to the process. They're
2272     * lazily setup to make sure the services are running when they're asked for.
2273     */
2274    private HashMap<String, IBinder> getCommonServicesLocked() {
2275        if (mAppBindArgs == null) {
2276            mAppBindArgs = new HashMap<String, IBinder>();
2277
2278            // Setup the application init args
2279            mAppBindArgs.put("package", ServiceManager.getService("package"));
2280            mAppBindArgs.put("window", ServiceManager.getService("window"));
2281            mAppBindArgs.put(Context.ALARM_SERVICE,
2282                    ServiceManager.getService(Context.ALARM_SERVICE));
2283        }
2284        return mAppBindArgs;
2285    }
2286
2287    final void setFocusedActivityLocked(ActivityRecord r) {
2288        if (mFocusedActivity != r) {
2289            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2290            mFocusedActivity = r;
2291            if (r.task != null && r.task.voiceInteractor != null) {
2292                startRunningVoiceLocked();
2293            } else {
2294                finishRunningVoiceLocked();
2295            }
2296            mStackSupervisor.setFocusedStack(r);
2297            if (r != null) {
2298                mWindowManager.setFocusedApp(r.appToken, true);
2299            }
2300            applyUpdateLockStateLocked(r);
2301        }
2302    }
2303
2304    final void clearFocusedActivity(ActivityRecord r) {
2305        if (mFocusedActivity == r) {
2306            mFocusedActivity = null;
2307        }
2308    }
2309
2310    @Override
2311    public void setFocusedStack(int stackId) {
2312        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2313        synchronized (ActivityManagerService.this) {
2314            ActivityStack stack = mStackSupervisor.getStack(stackId);
2315            if (stack != null) {
2316                ActivityRecord r = stack.topRunningActivityLocked(null);
2317                if (r != null) {
2318                    setFocusedActivityLocked(r);
2319                }
2320            }
2321        }
2322    }
2323
2324    @Override
2325    public void notifyActivityDrawn(IBinder token) {
2326        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2327        synchronized (this) {
2328            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2329            if (r != null) {
2330                r.task.stack.notifyActivityDrawnLocked(r);
2331            }
2332        }
2333    }
2334
2335    final void applyUpdateLockStateLocked(ActivityRecord r) {
2336        // Modifications to the UpdateLock state are done on our handler, outside
2337        // the activity manager's locks.  The new state is determined based on the
2338        // state *now* of the relevant activity record.  The object is passed to
2339        // the handler solely for logging detail, not to be consulted/modified.
2340        final boolean nextState = r != null && r.immersive;
2341        mHandler.sendMessage(
2342                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2343    }
2344
2345    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2346        Message msg = Message.obtain();
2347        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2348        msg.obj = r.task.askedCompatMode ? null : r;
2349        mHandler.sendMessage(msg);
2350    }
2351
2352    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2353            String what, Object obj, ProcessRecord srcApp) {
2354        app.lastActivityTime = now;
2355
2356        if (app.activities.size() > 0) {
2357            // Don't want to touch dependent processes that are hosting activities.
2358            return index;
2359        }
2360
2361        int lrui = mLruProcesses.lastIndexOf(app);
2362        if (lrui < 0) {
2363            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2364                    + what + " " + obj + " from " + srcApp);
2365            return index;
2366        }
2367
2368        if (lrui >= index) {
2369            // Don't want to cause this to move dependent processes *back* in the
2370            // list as if they were less frequently used.
2371            return index;
2372        }
2373
2374        if (lrui >= mLruProcessActivityStart) {
2375            // Don't want to touch dependent processes that are hosting activities.
2376            return index;
2377        }
2378
2379        mLruProcesses.remove(lrui);
2380        if (index > 0) {
2381            index--;
2382        }
2383        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2384                + " in LRU list: " + app);
2385        mLruProcesses.add(index, app);
2386        return index;
2387    }
2388
2389    final void removeLruProcessLocked(ProcessRecord app) {
2390        int lrui = mLruProcesses.lastIndexOf(app);
2391        if (lrui >= 0) {
2392            if (!app.killed) {
2393                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
2394                Process.killProcessQuiet(app.pid);
2395                Process.killProcessGroup(app.info.uid, app.pid);
2396            }
2397            if (lrui <= mLruProcessActivityStart) {
2398                mLruProcessActivityStart--;
2399            }
2400            if (lrui <= mLruProcessServiceStart) {
2401                mLruProcessServiceStart--;
2402            }
2403            mLruProcesses.remove(lrui);
2404        }
2405    }
2406
2407    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2408            ProcessRecord client) {
2409        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2410                || app.treatLikeActivity;
2411        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2412        if (!activityChange && hasActivity) {
2413            // The process has activities, so we are only allowing activity-based adjustments
2414            // to move it.  It should be kept in the front of the list with other
2415            // processes that have activities, and we don't want those to change their
2416            // order except due to activity operations.
2417            return;
2418        }
2419
2420        mLruSeq++;
2421        final long now = SystemClock.uptimeMillis();
2422        app.lastActivityTime = now;
2423
2424        // First a quick reject: if the app is already at the position we will
2425        // put it, then there is nothing to do.
2426        if (hasActivity) {
2427            final int N = mLruProcesses.size();
2428            if (N > 0 && mLruProcesses.get(N-1) == app) {
2429                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2430                return;
2431            }
2432        } else {
2433            if (mLruProcessServiceStart > 0
2434                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2435                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2436                return;
2437            }
2438        }
2439
2440        int lrui = mLruProcesses.lastIndexOf(app);
2441
2442        if (app.persistent && lrui >= 0) {
2443            // We don't care about the position of persistent processes, as long as
2444            // they are in the list.
2445            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2446            return;
2447        }
2448
2449        /* In progress: compute new position first, so we can avoid doing work
2450           if the process is not actually going to move.  Not yet working.
2451        int addIndex;
2452        int nextIndex;
2453        boolean inActivity = false, inService = false;
2454        if (hasActivity) {
2455            // Process has activities, put it at the very tipsy-top.
2456            addIndex = mLruProcesses.size();
2457            nextIndex = mLruProcessServiceStart;
2458            inActivity = true;
2459        } else if (hasService) {
2460            // Process has services, put it at the top of the service list.
2461            addIndex = mLruProcessActivityStart;
2462            nextIndex = mLruProcessServiceStart;
2463            inActivity = true;
2464            inService = true;
2465        } else  {
2466            // Process not otherwise of interest, it goes to the top of the non-service area.
2467            addIndex = mLruProcessServiceStart;
2468            if (client != null) {
2469                int clientIndex = mLruProcesses.lastIndexOf(client);
2470                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2471                        + app);
2472                if (clientIndex >= 0 && addIndex > clientIndex) {
2473                    addIndex = clientIndex;
2474                }
2475            }
2476            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2477        }
2478
2479        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2480                + mLruProcessActivityStart + "): " + app);
2481        */
2482
2483        if (lrui >= 0) {
2484            if (lrui < mLruProcessActivityStart) {
2485                mLruProcessActivityStart--;
2486            }
2487            if (lrui < mLruProcessServiceStart) {
2488                mLruProcessServiceStart--;
2489            }
2490            /*
2491            if (addIndex > lrui) {
2492                addIndex--;
2493            }
2494            if (nextIndex > lrui) {
2495                nextIndex--;
2496            }
2497            */
2498            mLruProcesses.remove(lrui);
2499        }
2500
2501        /*
2502        mLruProcesses.add(addIndex, app);
2503        if (inActivity) {
2504            mLruProcessActivityStart++;
2505        }
2506        if (inService) {
2507            mLruProcessActivityStart++;
2508        }
2509        */
2510
2511        int nextIndex;
2512        if (hasActivity) {
2513            final int N = mLruProcesses.size();
2514            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2515                // Process doesn't have activities, but has clients with
2516                // activities...  move it up, but one below the top (the top
2517                // should always have a real activity).
2518                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2519                mLruProcesses.add(N-1, app);
2520                // To keep it from spamming the LRU list (by making a bunch of clients),
2521                // we will push down any other entries owned by the app.
2522                final int uid = app.info.uid;
2523                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2524                    ProcessRecord subProc = mLruProcesses.get(i);
2525                    if (subProc.info.uid == uid) {
2526                        // We want to push this one down the list.  If the process after
2527                        // it is for the same uid, however, don't do so, because we don't
2528                        // want them internally to be re-ordered.
2529                        if (mLruProcesses.get(i-1).info.uid != uid) {
2530                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2531                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2532                            ProcessRecord tmp = mLruProcesses.get(i);
2533                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2534                            mLruProcesses.set(i-1, tmp);
2535                            i--;
2536                        }
2537                    } else {
2538                        // A gap, we can stop here.
2539                        break;
2540                    }
2541                }
2542            } else {
2543                // Process has activities, put it at the very tipsy-top.
2544                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2545                mLruProcesses.add(app);
2546            }
2547            nextIndex = mLruProcessServiceStart;
2548        } else if (hasService) {
2549            // Process has services, put it at the top of the service list.
2550            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2551            mLruProcesses.add(mLruProcessActivityStart, app);
2552            nextIndex = mLruProcessServiceStart;
2553            mLruProcessActivityStart++;
2554        } else  {
2555            // Process not otherwise of interest, it goes to the top of the non-service area.
2556            int index = mLruProcessServiceStart;
2557            if (client != null) {
2558                // If there is a client, don't allow the process to be moved up higher
2559                // in the list than that client.
2560                int clientIndex = mLruProcesses.lastIndexOf(client);
2561                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2562                        + " when updating " + app);
2563                if (clientIndex <= lrui) {
2564                    // Don't allow the client index restriction to push it down farther in the
2565                    // list than it already is.
2566                    clientIndex = lrui;
2567                }
2568                if (clientIndex >= 0 && index > clientIndex) {
2569                    index = clientIndex;
2570                }
2571            }
2572            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2573            mLruProcesses.add(index, app);
2574            nextIndex = index-1;
2575            mLruProcessActivityStart++;
2576            mLruProcessServiceStart++;
2577        }
2578
2579        // If the app is currently using a content provider or service,
2580        // bump those processes as well.
2581        for (int j=app.connections.size()-1; j>=0; j--) {
2582            ConnectionRecord cr = app.connections.valueAt(j);
2583            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2584                    && cr.binding.service.app != null
2585                    && cr.binding.service.app.lruSeq != mLruSeq
2586                    && !cr.binding.service.app.persistent) {
2587                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2588                        "service connection", cr, app);
2589            }
2590        }
2591        for (int j=app.conProviders.size()-1; j>=0; j--) {
2592            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2593            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2594                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2595                        "provider reference", cpr, app);
2596            }
2597        }
2598    }
2599
2600    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2601        if (uid == Process.SYSTEM_UID) {
2602            // The system gets to run in any process.  If there are multiple
2603            // processes with the same uid, just pick the first (this
2604            // should never happen).
2605            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2606            if (procs == null) return null;
2607            final int N = procs.size();
2608            for (int i = 0; i < N; i++) {
2609                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2610            }
2611        }
2612        ProcessRecord proc = mProcessNames.get(processName, uid);
2613        if (false && proc != null && !keepIfLarge
2614                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2615                && proc.lastCachedPss >= 4000) {
2616            // Turn this condition on to cause killing to happen regularly, for testing.
2617            if (proc.baseProcessTracker != null) {
2618                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2619            }
2620            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2621        } else if (proc != null && !keepIfLarge
2622                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2623                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2624            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2625            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2626                if (proc.baseProcessTracker != null) {
2627                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2628                }
2629                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2630            }
2631        }
2632        return proc;
2633    }
2634
2635    void ensurePackageDexOpt(String packageName) {
2636        IPackageManager pm = AppGlobals.getPackageManager();
2637        try {
2638            if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) {
2639                mDidDexOpt = true;
2640            }
2641        } catch (RemoteException e) {
2642        }
2643    }
2644
2645    boolean isNextTransitionForward() {
2646        int transit = mWindowManager.getPendingAppTransition();
2647        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2648                || transit == AppTransition.TRANSIT_TASK_OPEN
2649                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2650    }
2651
2652    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
2653            String processName, String abiOverride, int uid, Runnable crashHandler) {
2654        synchronized(this) {
2655            ApplicationInfo info = new ApplicationInfo();
2656            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
2657            // For isolated processes, the former contains the parent's uid and the latter the
2658            // actual uid of the isolated process.
2659            // In the special case introduced by this method (which is, starting an isolated
2660            // process directly from the SystemServer without an actual parent app process) the
2661            // closest thing to a parent's uid is SYSTEM_UID.
2662            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
2663            // the |isolated| logic in the ProcessRecord constructor.
2664            info.uid = Process.SYSTEM_UID;
2665            info.processName = processName;
2666            info.className = entryPoint;
2667            info.packageName = "android";
2668            ProcessRecord proc = startProcessLocked(processName, info /* info */,
2669                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
2670                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
2671                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
2672                    crashHandler);
2673            return proc != null ? proc.pid : 0;
2674        }
2675    }
2676
2677    final ProcessRecord startProcessLocked(String processName,
2678            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2679            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2680            boolean isolated, boolean keepIfLarge) {
2681        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
2682                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
2683                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
2684                null /* crashHandler */);
2685    }
2686
2687    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
2688            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
2689            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
2690            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
2691        long startTime = SystemClock.elapsedRealtime();
2692        ProcessRecord app;
2693        if (!isolated) {
2694            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2695            checkTime(startTime, "startProcess: after getProcessRecord");
2696        } else {
2697            // If this is an isolated process, it can't re-use an existing process.
2698            app = null;
2699        }
2700        // We don't have to do anything more if:
2701        // (1) There is an existing application record; and
2702        // (2) The caller doesn't think it is dead, OR there is no thread
2703        //     object attached to it so we know it couldn't have crashed; and
2704        // (3) There is a pid assigned to it, so it is either starting or
2705        //     already running.
2706        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2707                + " app=" + app + " knownToBeDead=" + knownToBeDead
2708                + " thread=" + (app != null ? app.thread : null)
2709                + " pid=" + (app != null ? app.pid : -1));
2710        if (app != null && app.pid > 0) {
2711            if (!knownToBeDead || app.thread == null) {
2712                // We already have the app running, or are waiting for it to
2713                // come up (we have a pid but not yet its thread), so keep it.
2714                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2715                // If this is a new package in the process, add the package to the list
2716                app.addPackage(info.packageName, info.versionCode, mProcessStats);
2717                checkTime(startTime, "startProcess: done, added package to proc");
2718                return app;
2719            }
2720
2721            // An application record is attached to a previous process,
2722            // clean it up now.
2723            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2724            checkTime(startTime, "startProcess: bad proc running, killing");
2725            Process.killProcessGroup(app.info.uid, app.pid);
2726            handleAppDiedLocked(app, true, true);
2727            checkTime(startTime, "startProcess: done killing old proc");
2728        }
2729
2730        String hostingNameStr = hostingName != null
2731                ? hostingName.flattenToShortString() : null;
2732
2733        if (!isolated) {
2734            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2735                // If we are in the background, then check to see if this process
2736                // is bad.  If so, we will just silently fail.
2737                if (mBadProcesses.get(info.processName, info.uid) != null) {
2738                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2739                            + "/" + info.processName);
2740                    return null;
2741                }
2742            } else {
2743                // When the user is explicitly starting a process, then clear its
2744                // crash count so that we won't make it bad until they see at
2745                // least one crash dialog again, and make the process good again
2746                // if it had been bad.
2747                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2748                        + "/" + info.processName);
2749                mProcessCrashTimes.remove(info.processName, info.uid);
2750                if (mBadProcesses.get(info.processName, info.uid) != null) {
2751                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2752                            UserHandle.getUserId(info.uid), info.uid,
2753                            info.processName);
2754                    mBadProcesses.remove(info.processName, info.uid);
2755                    if (app != null) {
2756                        app.bad = false;
2757                    }
2758                }
2759            }
2760        }
2761
2762        if (app == null) {
2763            checkTime(startTime, "startProcess: creating new process record");
2764            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
2765            app.crashHandler = crashHandler;
2766            if (app == null) {
2767                Slog.w(TAG, "Failed making new process record for "
2768                        + processName + "/" + info.uid + " isolated=" + isolated);
2769                return null;
2770            }
2771            mProcessNames.put(processName, app.uid, app);
2772            if (isolated) {
2773                mIsolatedProcesses.put(app.uid, app);
2774            }
2775            checkTime(startTime, "startProcess: done creating new process record");
2776        } else {
2777            // If this is a new package in the process, add the package to the list
2778            app.addPackage(info.packageName, info.versionCode, mProcessStats);
2779            checkTime(startTime, "startProcess: added package to existing proc");
2780        }
2781
2782        // If the system is not ready yet, then hold off on starting this
2783        // process until it is.
2784        if (!mProcessesReady
2785                && !isAllowedWhileBooting(info)
2786                && !allowWhileBooting) {
2787            if (!mProcessesOnHold.contains(app)) {
2788                mProcessesOnHold.add(app);
2789            }
2790            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2791            checkTime(startTime, "startProcess: returning with proc on hold");
2792            return app;
2793        }
2794
2795        checkTime(startTime, "startProcess: stepping in to startProcess");
2796        startProcessLocked(
2797                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
2798        checkTime(startTime, "startProcess: done starting proc!");
2799        return (app.pid != 0) ? app : null;
2800    }
2801
2802    boolean isAllowedWhileBooting(ApplicationInfo ai) {
2803        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2804    }
2805
2806    private final void startProcessLocked(ProcessRecord app,
2807            String hostingType, String hostingNameStr) {
2808        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
2809                null /* entryPoint */, null /* entryPointArgs */);
2810    }
2811
2812    private final void startProcessLocked(ProcessRecord app, String hostingType,
2813            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
2814        long startTime = SystemClock.elapsedRealtime();
2815        if (app.pid > 0 && app.pid != MY_PID) {
2816            checkTime(startTime, "startProcess: removing from pids map");
2817            synchronized (mPidsSelfLocked) {
2818                mPidsSelfLocked.remove(app.pid);
2819                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2820            }
2821            checkTime(startTime, "startProcess: done removing from pids map");
2822            app.setPid(0);
2823        }
2824
2825        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2826                "startProcessLocked removing on hold: " + app);
2827        mProcessesOnHold.remove(app);
2828
2829        checkTime(startTime, "startProcess: starting to update cpu stats");
2830        updateCpuStats();
2831        checkTime(startTime, "startProcess: done updating cpu stats");
2832
2833        try {
2834            int uid = app.uid;
2835
2836            int[] gids = null;
2837            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2838            if (!app.isolated) {
2839                int[] permGids = null;
2840                try {
2841                    checkTime(startTime, "startProcess: getting gids from package manager");
2842                    final PackageManager pm = mContext.getPackageManager();
2843                    permGids = pm.getPackageGids(app.info.packageName);
2844
2845                    if (Environment.isExternalStorageEmulated()) {
2846                        checkTime(startTime, "startProcess: checking external storage perm");
2847                        if (pm.checkPermission(
2848                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2849                                app.info.packageName) == PERMISSION_GRANTED) {
2850                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2851                        } else {
2852                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2853                        }
2854                    }
2855                } catch (PackageManager.NameNotFoundException e) {
2856                    Slog.w(TAG, "Unable to retrieve gids", e);
2857                }
2858
2859                /*
2860                 * Add shared application and profile GIDs so applications can share some
2861                 * resources like shared libraries and access user-wide resources
2862                 */
2863                if (permGids == null) {
2864                    gids = new int[2];
2865                } else {
2866                    gids = new int[permGids.length + 2];
2867                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
2868                }
2869                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
2870                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
2871            }
2872            checkTime(startTime, "startProcess: building args");
2873            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
2874                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2875                        && mTopComponent != null
2876                        && app.processName.equals(mTopComponent.getPackageName())) {
2877                    uid = 0;
2878                }
2879                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
2880                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2881                    uid = 0;
2882                }
2883            }
2884            int debugFlags = 0;
2885            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2886                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2887                // Also turn on CheckJNI for debuggable apps. It's quite
2888                // awkward to turn on otherwise.
2889                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2890            }
2891            // Run the app in safe mode if its manifest requests so or the
2892            // system is booted in safe mode.
2893            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2894                mSafeMode == true) {
2895                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2896            }
2897            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2898                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2899            }
2900            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2901                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
2902            }
2903            if ("1".equals(SystemProperties.get("debug.assert"))) {
2904                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2905            }
2906
2907            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
2908            if (requiredAbi == null) {
2909                requiredAbi = Build.SUPPORTED_ABIS[0];
2910            }
2911
2912            String instructionSet = null;
2913            if (app.info.primaryCpuAbi != null) {
2914                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
2915            }
2916
2917            // Start the process.  It will either succeed and return a result containing
2918            // the PID of the new process, or else throw a RuntimeException.
2919            boolean isActivityProcess = (entryPoint == null);
2920            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
2921            checkTime(startTime, "startProcess: asking zygote to start proc");
2922            Process.ProcessStartResult startResult = Process.start(entryPoint,
2923                    app.processName, uid, uid, gids, debugFlags, mountExternal,
2924                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
2925                    app.info.dataDir, entryPointArgs);
2926            checkTime(startTime, "startProcess: returned from zygote!");
2927
2928            if (app.isolated) {
2929                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
2930            }
2931            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
2932            checkTime(startTime, "startProcess: done updating battery stats");
2933
2934            EventLog.writeEvent(EventLogTags.AM_PROC_START,
2935                    UserHandle.getUserId(uid), startResult.pid, uid,
2936                    app.processName, hostingType,
2937                    hostingNameStr != null ? hostingNameStr : "");
2938
2939            if (app.persistent) {
2940                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
2941            }
2942
2943            checkTime(startTime, "startProcess: building log message");
2944            StringBuilder buf = mStringBuilder;
2945            buf.setLength(0);
2946            buf.append("Start proc ");
2947            buf.append(app.processName);
2948            if (!isActivityProcess) {
2949                buf.append(" [");
2950                buf.append(entryPoint);
2951                buf.append("]");
2952            }
2953            buf.append(" for ");
2954            buf.append(hostingType);
2955            if (hostingNameStr != null) {
2956                buf.append(" ");
2957                buf.append(hostingNameStr);
2958            }
2959            buf.append(": pid=");
2960            buf.append(startResult.pid);
2961            buf.append(" uid=");
2962            buf.append(uid);
2963            buf.append(" gids={");
2964            if (gids != null) {
2965                for (int gi=0; gi<gids.length; gi++) {
2966                    if (gi != 0) buf.append(", ");
2967                    buf.append(gids[gi]);
2968
2969                }
2970            }
2971            buf.append("}");
2972            if (requiredAbi != null) {
2973                buf.append(" abi=");
2974                buf.append(requiredAbi);
2975            }
2976            Slog.i(TAG, buf.toString());
2977            app.setPid(startResult.pid);
2978            app.usingWrapper = startResult.usingWrapper;
2979            app.removed = false;
2980            app.killed = false;
2981            app.killedByAm = false;
2982            checkTime(startTime, "startProcess: starting to update pids map");
2983            synchronized (mPidsSelfLocked) {
2984                this.mPidsSelfLocked.put(startResult.pid, app);
2985                if (isActivityProcess) {
2986                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
2987                    msg.obj = app;
2988                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
2989                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
2990                }
2991            }
2992            checkTime(startTime, "startProcess: done updating pids map");
2993        } catch (RuntimeException e) {
2994            // XXX do better error recovery.
2995            app.setPid(0);
2996            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
2997            if (app.isolated) {
2998                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
2999            }
3000            Slog.e(TAG, "Failure starting process " + app.processName, e);
3001        }
3002    }
3003
3004    void updateUsageStats(ActivityRecord component, boolean resumed) {
3005        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
3006        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3007        if (resumed) {
3008            if (mUsageStatsService != null) {
3009                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3010                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3011            }
3012            synchronized (stats) {
3013                stats.noteActivityResumedLocked(component.app.uid);
3014            }
3015        } else {
3016            if (mUsageStatsService != null) {
3017                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3018                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3019            }
3020            synchronized (stats) {
3021                stats.noteActivityPausedLocked(component.app.uid);
3022            }
3023        }
3024    }
3025
3026    Intent getHomeIntent() {
3027        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3028        intent.setComponent(mTopComponent);
3029        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3030            intent.addCategory(Intent.CATEGORY_HOME);
3031        }
3032        return intent;
3033    }
3034
3035    boolean startHomeActivityLocked(int userId) {
3036        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3037                && mTopAction == null) {
3038            // We are running in factory test mode, but unable to find
3039            // the factory test app, so just sit around displaying the
3040            // error message and don't try to start anything.
3041            return false;
3042        }
3043        Intent intent = getHomeIntent();
3044        ActivityInfo aInfo =
3045            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3046        if (aInfo != null) {
3047            intent.setComponent(new ComponentName(
3048                    aInfo.applicationInfo.packageName, aInfo.name));
3049            // Don't do this if the home app is currently being
3050            // instrumented.
3051            aInfo = new ActivityInfo(aInfo);
3052            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3053            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3054                    aInfo.applicationInfo.uid, true);
3055            if (app == null || app.instrumentationClass == null) {
3056                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3057                mStackSupervisor.startHomeActivity(intent, aInfo);
3058            }
3059        }
3060
3061        return true;
3062    }
3063
3064    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3065        ActivityInfo ai = null;
3066        ComponentName comp = intent.getComponent();
3067        try {
3068            if (comp != null) {
3069                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3070            } else {
3071                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3072                        intent,
3073                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3074                            flags, userId);
3075
3076                if (info != null) {
3077                    ai = info.activityInfo;
3078                }
3079            }
3080        } catch (RemoteException e) {
3081            // ignore
3082        }
3083
3084        return ai;
3085    }
3086
3087    /**
3088     * Starts the "new version setup screen" if appropriate.
3089     */
3090    void startSetupActivityLocked() {
3091        // Only do this once per boot.
3092        if (mCheckedForSetup) {
3093            return;
3094        }
3095
3096        // We will show this screen if the current one is a different
3097        // version than the last one shown, and we are not running in
3098        // low-level factory test mode.
3099        final ContentResolver resolver = mContext.getContentResolver();
3100        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3101                Settings.Global.getInt(resolver,
3102                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3103            mCheckedForSetup = true;
3104
3105            // See if we should be showing the platform update setup UI.
3106            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3107            List<ResolveInfo> ris = mContext.getPackageManager()
3108                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3109
3110            // We don't allow third party apps to replace this.
3111            ResolveInfo ri = null;
3112            for (int i=0; ris != null && i<ris.size(); i++) {
3113                if ((ris.get(i).activityInfo.applicationInfo.flags
3114                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3115                    ri = ris.get(i);
3116                    break;
3117                }
3118            }
3119
3120            if (ri != null) {
3121                String vers = ri.activityInfo.metaData != null
3122                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3123                        : null;
3124                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3125                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3126                            Intent.METADATA_SETUP_VERSION);
3127                }
3128                String lastVers = Settings.Secure.getString(
3129                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3130                if (vers != null && !vers.equals(lastVers)) {
3131                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3132                    intent.setComponent(new ComponentName(
3133                            ri.activityInfo.packageName, ri.activityInfo.name));
3134                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3135                            null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, null, null,
3136                            null);
3137                }
3138            }
3139        }
3140    }
3141
3142    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3143        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3144    }
3145
3146    void enforceNotIsolatedCaller(String caller) {
3147        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3148            throw new SecurityException("Isolated process not allowed to call " + caller);
3149        }
3150    }
3151
3152    void enforceShellRestriction(String restriction, int userHandle) {
3153        if (Binder.getCallingUid() == Process.SHELL_UID) {
3154            if (userHandle < 0
3155                    || mUserManager.hasUserRestriction(restriction, userHandle)) {
3156                throw new SecurityException("Shell does not have permission to access user "
3157                        + userHandle);
3158            }
3159        }
3160    }
3161
3162    @Override
3163    public int getFrontActivityScreenCompatMode() {
3164        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3165        synchronized (this) {
3166            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3167        }
3168    }
3169
3170    @Override
3171    public void setFrontActivityScreenCompatMode(int mode) {
3172        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3173                "setFrontActivityScreenCompatMode");
3174        synchronized (this) {
3175            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3176        }
3177    }
3178
3179    @Override
3180    public int getPackageScreenCompatMode(String packageName) {
3181        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3182        synchronized (this) {
3183            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3184        }
3185    }
3186
3187    @Override
3188    public void setPackageScreenCompatMode(String packageName, int mode) {
3189        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3190                "setPackageScreenCompatMode");
3191        synchronized (this) {
3192            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3193        }
3194    }
3195
3196    @Override
3197    public boolean getPackageAskScreenCompat(String packageName) {
3198        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3199        synchronized (this) {
3200            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3201        }
3202    }
3203
3204    @Override
3205    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3206        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3207                "setPackageAskScreenCompat");
3208        synchronized (this) {
3209            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3210        }
3211    }
3212
3213    private void dispatchProcessesChanged() {
3214        int N;
3215        synchronized (this) {
3216            N = mPendingProcessChanges.size();
3217            if (mActiveProcessChanges.length < N) {
3218                mActiveProcessChanges = new ProcessChangeItem[N];
3219            }
3220            mPendingProcessChanges.toArray(mActiveProcessChanges);
3221            mAvailProcessChanges.addAll(mPendingProcessChanges);
3222            mPendingProcessChanges.clear();
3223            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3224        }
3225
3226        int i = mProcessObservers.beginBroadcast();
3227        while (i > 0) {
3228            i--;
3229            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3230            if (observer != null) {
3231                try {
3232                    for (int j=0; j<N; j++) {
3233                        ProcessChangeItem item = mActiveProcessChanges[j];
3234                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3235                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3236                                    + item.pid + " uid=" + item.uid + ": "
3237                                    + item.foregroundActivities);
3238                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3239                                    item.foregroundActivities);
3240                        }
3241                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3242                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3243                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
3244                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3245                        }
3246                    }
3247                } catch (RemoteException e) {
3248                }
3249            }
3250        }
3251        mProcessObservers.finishBroadcast();
3252    }
3253
3254    private void dispatchProcessDied(int pid, int uid) {
3255        int i = mProcessObservers.beginBroadcast();
3256        while (i > 0) {
3257            i--;
3258            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3259            if (observer != null) {
3260                try {
3261                    observer.onProcessDied(pid, uid);
3262                } catch (RemoteException e) {
3263                }
3264            }
3265        }
3266        mProcessObservers.finishBroadcast();
3267    }
3268
3269    @Override
3270    public final int startActivity(IApplicationThread caller, String callingPackage,
3271            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3272            int startFlags, ProfilerInfo profilerInfo, Bundle options) {
3273        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3274            resultWho, requestCode, startFlags, profilerInfo, options,
3275            UserHandle.getCallingUserId());
3276    }
3277
3278    @Override
3279    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3280            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3281            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3282        enforceNotIsolatedCaller("startActivity");
3283        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3284                false, ALLOW_FULL_ONLY, "startActivity", null);
3285        // TODO: Switch to user app stacks here.
3286        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3287                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3288                profilerInfo, null, null, options, userId, null, null);
3289    }
3290
3291    @Override
3292    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
3293            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3294            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3295
3296        // This is very dangerous -- it allows you to perform a start activity (including
3297        // permission grants) as any app that may launch one of your own activities.  So
3298        // we will only allow this to be done from activities that are part of the core framework,
3299        // and then only when they are running as the system.
3300        final ActivityRecord sourceRecord;
3301        final int targetUid;
3302        final String targetPackage;
3303        synchronized (this) {
3304            if (resultTo == null) {
3305                throw new SecurityException("Must be called from an activity");
3306            }
3307            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
3308            if (sourceRecord == null) {
3309                throw new SecurityException("Called with bad activity token: " + resultTo);
3310            }
3311            if (!sourceRecord.info.packageName.equals("android")) {
3312                throw new SecurityException(
3313                        "Must be called from an activity that is declared in the android package");
3314            }
3315            if (sourceRecord.app == null) {
3316                throw new SecurityException("Called without a process attached to activity");
3317            }
3318            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
3319                // This is still okay, as long as this activity is running under the
3320                // uid of the original calling activity.
3321                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
3322                    throw new SecurityException(
3323                            "Calling activity in uid " + sourceRecord.app.uid
3324                                    + " must be system uid or original calling uid "
3325                                    + sourceRecord.launchedFromUid);
3326                }
3327            }
3328            targetUid = sourceRecord.launchedFromUid;
3329            targetPackage = sourceRecord.launchedFromPackage;
3330        }
3331
3332        if (userId == UserHandle.USER_NULL) {
3333            userId = UserHandle.getUserId(sourceRecord.app.uid);
3334        }
3335
3336        // TODO: Switch to user app stacks here.
3337        try {
3338            int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent,
3339                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
3340                    null, null, options, userId, null, null);
3341            return ret;
3342        } catch (SecurityException e) {
3343            // XXX need to figure out how to propagate to original app.
3344            // A SecurityException here is generally actually a fault of the original
3345            // calling activity (such as a fairly granting permissions), so propagate it
3346            // back to them.
3347            /*
3348            StringBuilder msg = new StringBuilder();
3349            msg.append("While launching");
3350            msg.append(intent.toString());
3351            msg.append(": ");
3352            msg.append(e.getMessage());
3353            */
3354            throw e;
3355        }
3356    }
3357
3358    @Override
3359    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3360            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3361            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3362        enforceNotIsolatedCaller("startActivityAndWait");
3363        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3364                false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
3365        WaitResult res = new WaitResult();
3366        // TODO: Switch to user app stacks here.
3367        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3368                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
3369                options, userId, null, null);
3370        return res;
3371    }
3372
3373    @Override
3374    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3375            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3376            int startFlags, Configuration config, Bundle options, int userId) {
3377        enforceNotIsolatedCaller("startActivityWithConfig");
3378        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3379                false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
3380        // TODO: Switch to user app stacks here.
3381        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3382                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3383                null, null, config, options, userId, null, null);
3384        return ret;
3385    }
3386
3387    @Override
3388    public int startActivityIntentSender(IApplicationThread caller,
3389            IntentSender intent, Intent fillInIntent, String resolvedType,
3390            IBinder resultTo, String resultWho, int requestCode,
3391            int flagsMask, int flagsValues, Bundle options) {
3392        enforceNotIsolatedCaller("startActivityIntentSender");
3393        // Refuse possible leaked file descriptors
3394        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3395            throw new IllegalArgumentException("File descriptors passed in Intent");
3396        }
3397
3398        IIntentSender sender = intent.getTarget();
3399        if (!(sender instanceof PendingIntentRecord)) {
3400            throw new IllegalArgumentException("Bad PendingIntent object");
3401        }
3402
3403        PendingIntentRecord pir = (PendingIntentRecord)sender;
3404
3405        synchronized (this) {
3406            // If this is coming from the currently resumed activity, it is
3407            // effectively saying that app switches are allowed at this point.
3408            final ActivityStack stack = getFocusedStack();
3409            if (stack.mResumedActivity != null &&
3410                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3411                mAppSwitchesAllowedTime = 0;
3412            }
3413        }
3414        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3415                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3416        return ret;
3417    }
3418
3419    @Override
3420    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3421            Intent intent, String resolvedType, IVoiceInteractionSession session,
3422            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
3423            Bundle options, int userId) {
3424        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3425                != PackageManager.PERMISSION_GRANTED) {
3426            String msg = "Permission Denial: startVoiceActivity() from pid="
3427                    + Binder.getCallingPid()
3428                    + ", uid=" + Binder.getCallingUid()
3429                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3430            Slog.w(TAG, msg);
3431            throw new SecurityException(msg);
3432        }
3433        if (session == null || interactor == null) {
3434            throw new NullPointerException("null session or interactor");
3435        }
3436        userId = handleIncomingUser(callingPid, callingUid, userId,
3437                false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
3438        // TODO: Switch to user app stacks here.
3439        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3440                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
3441                null, options, userId, null, null);
3442    }
3443
3444    @Override
3445    public boolean startNextMatchingActivity(IBinder callingActivity,
3446            Intent intent, Bundle options) {
3447        // Refuse possible leaked file descriptors
3448        if (intent != null && intent.hasFileDescriptors() == true) {
3449            throw new IllegalArgumentException("File descriptors passed in Intent");
3450        }
3451
3452        synchronized (this) {
3453            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3454            if (r == null) {
3455                ActivityOptions.abort(options);
3456                return false;
3457            }
3458            if (r.app == null || r.app.thread == null) {
3459                // The caller is not running...  d'oh!
3460                ActivityOptions.abort(options);
3461                return false;
3462            }
3463            intent = new Intent(intent);
3464            // The caller is not allowed to change the data.
3465            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3466            // And we are resetting to find the next component...
3467            intent.setComponent(null);
3468
3469            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3470
3471            ActivityInfo aInfo = null;
3472            try {
3473                List<ResolveInfo> resolves =
3474                    AppGlobals.getPackageManager().queryIntentActivities(
3475                            intent, r.resolvedType,
3476                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3477                            UserHandle.getCallingUserId());
3478
3479                // Look for the original activity in the list...
3480                final int N = resolves != null ? resolves.size() : 0;
3481                for (int i=0; i<N; i++) {
3482                    ResolveInfo rInfo = resolves.get(i);
3483                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3484                            && rInfo.activityInfo.name.equals(r.info.name)) {
3485                        // We found the current one...  the next matching is
3486                        // after it.
3487                        i++;
3488                        if (i<N) {
3489                            aInfo = resolves.get(i).activityInfo;
3490                        }
3491                        if (debug) {
3492                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3493                                    + "/" + r.info.name);
3494                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3495                                    + "/" + aInfo.name);
3496                        }
3497                        break;
3498                    }
3499                }
3500            } catch (RemoteException e) {
3501            }
3502
3503            if (aInfo == null) {
3504                // Nobody who is next!
3505                ActivityOptions.abort(options);
3506                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3507                return false;
3508            }
3509
3510            intent.setComponent(new ComponentName(
3511                    aInfo.applicationInfo.packageName, aInfo.name));
3512            intent.setFlags(intent.getFlags()&~(
3513                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3514                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3515                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3516                    Intent.FLAG_ACTIVITY_NEW_TASK));
3517
3518            // Okay now we need to start the new activity, replacing the
3519            // currently running activity.  This is a little tricky because
3520            // we want to start the new one as if the current one is finished,
3521            // but not finish the current one first so that there is no flicker.
3522            // And thus...
3523            final boolean wasFinishing = r.finishing;
3524            r.finishing = true;
3525
3526            // Propagate reply information over to the new activity.
3527            final ActivityRecord resultTo = r.resultTo;
3528            final String resultWho = r.resultWho;
3529            final int requestCode = r.requestCode;
3530            r.resultTo = null;
3531            if (resultTo != null) {
3532                resultTo.removeResultsLocked(r, resultWho, requestCode);
3533            }
3534
3535            final long origId = Binder.clearCallingIdentity();
3536            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3537                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3538                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage,
3539                    -1, r.launchedFromUid, 0, options, false, null, null, null);
3540            Binder.restoreCallingIdentity(origId);
3541
3542            r.finishing = wasFinishing;
3543            if (res != ActivityManager.START_SUCCESS) {
3544                return false;
3545            }
3546            return true;
3547        }
3548    }
3549
3550    @Override
3551    public final int startActivityFromRecents(int taskId, Bundle options) {
3552        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
3553            String msg = "Permission Denial: startActivityFromRecents called without " +
3554                    START_TASKS_FROM_RECENTS;
3555            Slog.w(TAG, msg);
3556            throw new SecurityException(msg);
3557        }
3558        return startActivityFromRecentsInner(taskId, options);
3559    }
3560
3561    final int startActivityFromRecentsInner(int taskId, Bundle options) {
3562        final TaskRecord task;
3563        final int callingUid;
3564        final String callingPackage;
3565        final Intent intent;
3566        final int userId;
3567        synchronized (this) {
3568            task = recentTaskForIdLocked(taskId);
3569            if (task == null) {
3570                throw new IllegalArgumentException("Task " + taskId + " not found.");
3571            }
3572            callingUid = task.mCallingUid;
3573            callingPackage = task.mCallingPackage;
3574            intent = task.intent;
3575            intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
3576            userId = task.userId;
3577        }
3578        return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
3579                options, userId, null, task);
3580    }
3581
3582    final int startActivityInPackage(int uid, String callingPackage,
3583            Intent intent, String resolvedType, IBinder resultTo,
3584            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3585            IActivityContainer container, TaskRecord inTask) {
3586
3587        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3588                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3589
3590        // TODO: Switch to user app stacks here.
3591        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent,
3592                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3593                null, null, null, options, userId, container, inTask);
3594        return ret;
3595    }
3596
3597    @Override
3598    public final int startActivities(IApplicationThread caller, String callingPackage,
3599            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3600            int userId) {
3601        enforceNotIsolatedCaller("startActivities");
3602        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3603                false, ALLOW_FULL_ONLY, "startActivity", null);
3604        // TODO: Switch to user app stacks here.
3605        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3606                resolvedTypes, resultTo, options, userId);
3607        return ret;
3608    }
3609
3610    final int startActivitiesInPackage(int uid, String callingPackage,
3611            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3612            Bundle options, int userId) {
3613
3614        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3615                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3616        // TODO: Switch to user app stacks here.
3617        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3618                resultTo, options, userId);
3619        return ret;
3620    }
3621
3622    //explicitly remove thd old information in mRecentTasks when removing existing user.
3623    private void removeRecentTasksForUserLocked(int userId) {
3624        if(userId <= 0) {
3625            Slog.i(TAG, "Can't remove recent task on user " + userId);
3626            return;
3627        }
3628
3629        for (int i = mRecentTasks.size() - 1; i >= 0; --i) {
3630            TaskRecord tr = mRecentTasks.get(i);
3631            if (tr.userId == userId) {
3632                if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr
3633                        + " when finishing user" + userId);
3634                mRecentTasks.remove(i);
3635                tr.removedFromRecents(mTaskPersister);
3636            }
3637        }
3638
3639        // Remove tasks from persistent storage.
3640        mTaskPersister.wakeup(null, true);
3641    }
3642
3643    // Sort by taskId
3644    private Comparator<TaskRecord> mTaskRecordComparator = new Comparator<TaskRecord>() {
3645        @Override
3646        public int compare(TaskRecord lhs, TaskRecord rhs) {
3647            return rhs.taskId - lhs.taskId;
3648        }
3649    };
3650
3651    // Extract the affiliates of the chain containing mRecentTasks[start].
3652    private int processNextAffiliateChain(int start) {
3653        final TaskRecord startTask = mRecentTasks.get(start);
3654        final int affiliateId = startTask.mAffiliatedTaskId;
3655
3656        // Quick identification of isolated tasks. I.e. those not launched behind.
3657        if (startTask.taskId == affiliateId && startTask.mPrevAffiliate == null &&
3658                startTask.mNextAffiliate == null) {
3659            // There is still a slim chance that there are other tasks that point to this task
3660            // and that the chain is so messed up that this task no longer points to them but
3661            // the gain of this optimization outweighs the risk.
3662            startTask.inRecents = true;
3663            return start + 1;
3664        }
3665
3666        // Remove all tasks that are affiliated to affiliateId and put them in mTmpRecents.
3667        mTmpRecents.clear();
3668        for (int i = mRecentTasks.size() - 1; i >= start; --i) {
3669            final TaskRecord task = mRecentTasks.get(i);
3670            if (task.mAffiliatedTaskId == affiliateId) {
3671                mRecentTasks.remove(i);
3672                mTmpRecents.add(task);
3673            }
3674        }
3675
3676        // Sort them all by taskId. That is the order they were create in and that order will
3677        // always be correct.
3678        Collections.sort(mTmpRecents, mTaskRecordComparator);
3679
3680        // Go through and fix up the linked list.
3681        // The first one is the end of the chain and has no next.
3682        final TaskRecord first = mTmpRecents.get(0);
3683        first.inRecents = true;
3684        if (first.mNextAffiliate != null) {
3685            Slog.w(TAG, "Link error 1 first.next=" + first.mNextAffiliate);
3686            first.setNextAffiliate(null);
3687            mTaskPersister.wakeup(first, false);
3688        }
3689        // Everything in the middle is doubly linked from next to prev.
3690        final int tmpSize = mTmpRecents.size();
3691        for (int i = 0; i < tmpSize - 1; ++i) {
3692            final TaskRecord next = mTmpRecents.get(i);
3693            final TaskRecord prev = mTmpRecents.get(i + 1);
3694            if (next.mPrevAffiliate != prev) {
3695                Slog.w(TAG, "Link error 2 next=" + next + " prev=" + next.mPrevAffiliate +
3696                        " setting prev=" + prev);
3697                next.setPrevAffiliate(prev);
3698                mTaskPersister.wakeup(next, false);
3699            }
3700            if (prev.mNextAffiliate != next) {
3701                Slog.w(TAG, "Link error 3 prev=" + prev + " next=" + prev.mNextAffiliate +
3702                        " setting next=" + next);
3703                prev.setNextAffiliate(next);
3704                mTaskPersister.wakeup(prev, false);
3705            }
3706            prev.inRecents = true;
3707        }
3708        // The last one is the beginning of the list and has no prev.
3709        final TaskRecord last = mTmpRecents.get(tmpSize - 1);
3710        if (last.mPrevAffiliate != null) {
3711            Slog.w(TAG, "Link error 4 last.prev=" + last.mPrevAffiliate);
3712            last.setPrevAffiliate(null);
3713            mTaskPersister.wakeup(last, false);
3714        }
3715
3716        // Insert the group back into mRecentTasks at start.
3717        mRecentTasks.addAll(start, mTmpRecents);
3718
3719        // Let the caller know where we left off.
3720        return start + tmpSize;
3721    }
3722
3723    /**
3724     * Update the recent tasks lists: make sure tasks should still be here (their
3725     * applications / activities still exist), update their availability, fixup ordering
3726     * of affiliations.
3727     */
3728    void cleanupRecentTasksLocked(int userId) {
3729        if (mRecentTasks == null) {
3730            // Happens when called from the packagemanager broadcast before boot.
3731            return;
3732        }
3733
3734        final HashMap<ComponentName, ActivityInfo> availActCache = new HashMap<>();
3735        final HashMap<String, ApplicationInfo> availAppCache = new HashMap<>();
3736        final IPackageManager pm = AppGlobals.getPackageManager();
3737        final ActivityInfo dummyAct = new ActivityInfo();
3738        final ApplicationInfo dummyApp = new ApplicationInfo();
3739
3740        int N = mRecentTasks.size();
3741
3742        int[] users = userId == UserHandle.USER_ALL
3743                ? getUsersLocked() : new int[] { userId };
3744        for (int user : users) {
3745            for (int i = 0; i < N; i++) {
3746                TaskRecord task = mRecentTasks.get(i);
3747                if (task.userId != user) {
3748                    // Only look at tasks for the user ID of interest.
3749                    continue;
3750                }
3751                if (task.autoRemoveRecents && task.getTopActivity() == null) {
3752                    // This situation is broken, and we should just get rid of it now.
3753                    mRecentTasks.remove(i);
3754                    task.removedFromRecents(mTaskPersister);
3755                    i--;
3756                    N--;
3757                    Slog.w(TAG, "Removing auto-remove without activity: " + task);
3758                    continue;
3759                }
3760                // Check whether this activity is currently available.
3761                if (task.realActivity != null) {
3762                    ActivityInfo ai = availActCache.get(task.realActivity);
3763                    if (ai == null) {
3764                        try {
3765                            ai = pm.getActivityInfo(task.realActivity,
3766                                    PackageManager.GET_UNINSTALLED_PACKAGES
3767                                    | PackageManager.GET_DISABLED_COMPONENTS, user);
3768                        } catch (RemoteException e) {
3769                            // Will never happen.
3770                            continue;
3771                        }
3772                        if (ai == null) {
3773                            ai = dummyAct;
3774                        }
3775                        availActCache.put(task.realActivity, ai);
3776                    }
3777                    if (ai == dummyAct) {
3778                        // This could be either because the activity no longer exists, or the
3779                        // app is temporarily gone.  For the former we want to remove the recents
3780                        // entry; for the latter we want to mark it as unavailable.
3781                        ApplicationInfo app = availAppCache.get(task.realActivity.getPackageName());
3782                        if (app == null) {
3783                            try {
3784                                app = pm.getApplicationInfo(task.realActivity.getPackageName(),
3785                                        PackageManager.GET_UNINSTALLED_PACKAGES
3786                                        | PackageManager.GET_DISABLED_COMPONENTS, user);
3787                            } catch (RemoteException e) {
3788                                // Will never happen.
3789                                continue;
3790                            }
3791                            if (app == null) {
3792                                app = dummyApp;
3793                            }
3794                            availAppCache.put(task.realActivity.getPackageName(), app);
3795                        }
3796                        if (app == dummyApp || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
3797                            // Doesn't exist any more!  Good-bye.
3798                            mRecentTasks.remove(i);
3799                            task.removedFromRecents(mTaskPersister);
3800                            i--;
3801                            N--;
3802                            Slog.w(TAG, "Removing no longer valid recent: " + task);
3803                            continue;
3804                        } else {
3805                            // Otherwise just not available for now.
3806                            if (task.isAvailable) {
3807                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
3808                                        + task);
3809                            }
3810                            task.isAvailable = false;
3811                        }
3812                    } else {
3813                        if (!ai.enabled || !ai.applicationInfo.enabled
3814                                || (ai.applicationInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
3815                            if (task.isAvailable) {
3816                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
3817                                        + task + " (enabled=" + ai.enabled + "/"
3818                                        + ai.applicationInfo.enabled +  " flags="
3819                                        + Integer.toHexString(ai.applicationInfo.flags) + ")");
3820                            }
3821                            task.isAvailable = false;
3822                        } else {
3823                            if (!task.isAvailable) {
3824                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent available: "
3825                                        + task);
3826                            }
3827                            task.isAvailable = true;
3828                        }
3829                    }
3830                }
3831            }
3832        }
3833
3834        // Verify the affiliate chain for each task.
3835        for (int i = 0; i < N; i = processNextAffiliateChain(i)) {
3836        }
3837
3838        mTmpRecents.clear();
3839        // mRecentTasks is now in sorted, affiliated order.
3840    }
3841
3842    private final boolean moveAffiliatedTasksToFront(TaskRecord task, int taskIndex) {
3843        int N = mRecentTasks.size();
3844        TaskRecord top = task;
3845        int topIndex = taskIndex;
3846        while (top.mNextAffiliate != null && topIndex > 0) {
3847            top = top.mNextAffiliate;
3848            topIndex--;
3849        }
3850        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding affilliates starting at "
3851                + topIndex + " from intial " + taskIndex);
3852        // Find the end of the chain, doing a sanity check along the way.
3853        boolean sane = top.mAffiliatedTaskId == task.mAffiliatedTaskId;
3854        int endIndex = topIndex;
3855        TaskRecord prev = top;
3856        while (endIndex < N) {
3857            TaskRecord cur = mRecentTasks.get(endIndex);
3858            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: looking at next chain @"
3859                    + endIndex + " " + cur);
3860            if (cur == top) {
3861                // Verify start of the chain.
3862                if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != -1) {
3863                    Slog.wtf(TAG, "Bad chain @" + endIndex
3864                            + ": first task has next affiliate: " + prev);
3865                    sane = false;
3866                    break;
3867                }
3868            } else {
3869                // Verify middle of the chain's next points back to the one before.
3870                if (cur.mNextAffiliate != prev
3871                        || cur.mNextAffiliateTaskId != prev.taskId) {
3872                    Slog.wtf(TAG, "Bad chain @" + endIndex
3873                            + ": middle task " + cur + " @" + endIndex
3874                            + " has bad next affiliate "
3875                            + cur.mNextAffiliate + " id " + cur.mNextAffiliateTaskId
3876                            + ", expected " + prev);
3877                    sane = false;
3878                    break;
3879                }
3880            }
3881            if (cur.mPrevAffiliateTaskId == -1) {
3882                // Chain ends here.
3883                if (cur.mPrevAffiliate != null) {
3884                    Slog.wtf(TAG, "Bad chain @" + endIndex
3885                            + ": last task " + cur + " has previous affiliate "
3886                            + cur.mPrevAffiliate);
3887                    sane = false;
3888                }
3889                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: end of chain @" + endIndex);
3890                break;
3891            } else {
3892                // Verify middle of the chain's prev points to a valid item.
3893                if (cur.mPrevAffiliate == null) {
3894                    Slog.wtf(TAG, "Bad chain @" + endIndex
3895                            + ": task " + cur + " has previous affiliate "
3896                            + cur.mPrevAffiliate + " but should be id "
3897                            + cur.mPrevAffiliate);
3898                    sane = false;
3899                    break;
3900                }
3901            }
3902            if (cur.mAffiliatedTaskId != task.mAffiliatedTaskId) {
3903                Slog.wtf(TAG, "Bad chain @" + endIndex
3904                        + ": task " + cur + " has affiliated id "
3905                        + cur.mAffiliatedTaskId + " but should be "
3906                        + task.mAffiliatedTaskId);
3907                sane = false;
3908                break;
3909            }
3910            prev = cur;
3911            endIndex++;
3912            if (endIndex >= N) {
3913                Slog.wtf(TAG, "Bad chain ran off index " + endIndex
3914                        + ": last task " + prev);
3915                sane = false;
3916                break;
3917            }
3918        }
3919        if (sane) {
3920            if (endIndex < taskIndex) {
3921                Slog.wtf(TAG, "Bad chain @" + endIndex
3922                        + ": did not extend to task " + task + " @" + taskIndex);
3923                sane = false;
3924            }
3925        }
3926        if (sane) {
3927            // All looks good, we can just move all of the affiliated tasks
3928            // to the top.
3929            for (int i=topIndex; i<=endIndex; i++) {
3930                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving affiliated " + task
3931                        + " from " + i + " to " + (i-topIndex));
3932                TaskRecord cur = mRecentTasks.remove(i);
3933                mRecentTasks.add(i-topIndex, cur);
3934            }
3935            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: done moving tasks  " +  topIndex
3936                    + " to " + endIndex);
3937            return true;
3938        }
3939
3940        // Whoops, couldn't do it.
3941        return false;
3942    }
3943
3944    final void addRecentTaskLocked(TaskRecord task) {
3945        final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId
3946                || task.mNextAffiliateTaskId != -1 || task.mPrevAffiliateTaskId != -1;
3947
3948        int N = mRecentTasks.size();
3949        // Quick case: check if the top-most recent task is the same.
3950        if (!isAffiliated && N > 0 && mRecentTasks.get(0) == task) {
3951            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: already at top: " + task);
3952            return;
3953        }
3954        // Another quick case: check if this is part of a set of affiliated
3955        // tasks that are at the top.
3956        if (isAffiliated && N > 0 && task.inRecents
3957                && task.mAffiliatedTaskId == mRecentTasks.get(0).mAffiliatedTaskId) {
3958            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: affiliated " + mRecentTasks.get(0)
3959                    + " at top when adding " + task);
3960            return;
3961        }
3962        // Another quick case: never add voice sessions.
3963        if (task.voiceSession != null) {
3964            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: not adding voice interaction " + task);
3965            return;
3966        }
3967
3968        boolean needAffiliationFix = false;
3969
3970        // Slightly less quick case: the task is already in recents, so all we need
3971        // to do is move it.
3972        if (task.inRecents) {
3973            int taskIndex = mRecentTasks.indexOf(task);
3974            if (taskIndex >= 0) {
3975                if (!isAffiliated) {
3976                    // Simple case: this is not an affiliated task, so we just move it to the front.
3977                    mRecentTasks.remove(taskIndex);
3978                    mRecentTasks.add(0, task);
3979                    notifyTaskPersisterLocked(task, false);
3980                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving to top " + task
3981                            + " from " + taskIndex);
3982                    return;
3983                } else {
3984                    // More complicated: need to keep all affiliated tasks together.
3985                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
3986                        // All went well.
3987                        return;
3988                    }
3989
3990                    // Uh oh...  something bad in the affiliation chain, try to rebuild
3991                    // everything and then go through our general path of adding a new task.
3992                    needAffiliationFix = true;
3993                }
3994            } else {
3995                Slog.wtf(TAG, "Task with inRecent not in recents: " + task);
3996                needAffiliationFix = true;
3997            }
3998        }
3999
4000        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: trimming tasks for " + task);
4001        trimRecentsForTask(task, true);
4002
4003        N = mRecentTasks.size();
4004        while (N >= ActivityManager.getMaxRecentTasksStatic()) {
4005            final TaskRecord tr = mRecentTasks.remove(N - 1);
4006            tr.removedFromRecents(mTaskPersister);
4007            N--;
4008        }
4009        task.inRecents = true;
4010        if (!isAffiliated || needAffiliationFix) {
4011            // If this is a simple non-affiliated task, or we had some failure trying to
4012            // handle it as part of an affilated task, then just place it at the top.
4013            mRecentTasks.add(0, task);
4014        } else if (isAffiliated) {
4015            // If this is a new affiliated task, then move all of the affiliated tasks
4016            // to the front and insert this new one.
4017            TaskRecord other = task.mNextAffiliate;
4018            if (other == null) {
4019                other = task.mPrevAffiliate;
4020            }
4021            if (other != null) {
4022                int otherIndex = mRecentTasks.indexOf(other);
4023                if (otherIndex >= 0) {
4024                    // Insert new task at appropriate location.
4025                    int taskIndex;
4026                    if (other == task.mNextAffiliate) {
4027                        // We found the index of our next affiliation, which is who is
4028                        // before us in the list, so add after that point.
4029                        taskIndex = otherIndex+1;
4030                    } else {
4031                        // We found the index of our previous affiliation, which is who is
4032                        // after us in the list, so add at their position.
4033                        taskIndex = otherIndex;
4034                    }
4035                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: new affiliated task added at "
4036                            + taskIndex + ": " + task);
4037                    mRecentTasks.add(taskIndex, task);
4038
4039                    // Now move everything to the front.
4040                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
4041                        // All went well.
4042                        return;
4043                    }
4044
4045                    // Uh oh...  something bad in the affiliation chain, try to rebuild
4046                    // everything and then go through our general path of adding a new task.
4047                    needAffiliationFix = true;
4048                } else {
4049                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: couldn't find other affiliation "
4050                            + other);
4051                    needAffiliationFix = true;
4052                }
4053            } else {
4054                if (DEBUG_RECENTS) Slog.d(TAG,
4055                        "addRecent: adding affiliated task without next/prev:" + task);
4056                needAffiliationFix = true;
4057            }
4058        }
4059        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding " + task);
4060
4061        if (needAffiliationFix) {
4062            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: regrouping affiliations");
4063            cleanupRecentTasksLocked(task.userId);
4064        }
4065    }
4066
4067    /**
4068     * If needed, remove oldest existing entries in recents that are for the same kind
4069     * of task as the given one.
4070     */
4071    int trimRecentsForTask(TaskRecord task, boolean doTrim) {
4072        int N = mRecentTasks.size();
4073        final Intent intent = task.intent;
4074        final boolean document = intent != null && intent.isDocument();
4075
4076        int maxRecents = task.maxRecents - 1;
4077        for (int i=0; i<N; i++) {
4078            final TaskRecord tr = mRecentTasks.get(i);
4079            if (task != tr) {
4080                if (task.userId != tr.userId) {
4081                    continue;
4082                }
4083                if (i > MAX_RECENT_BITMAPS) {
4084                    tr.freeLastThumbnail();
4085                }
4086                final Intent trIntent = tr.intent;
4087                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
4088                    (intent == null || !intent.filterEquals(trIntent))) {
4089                    continue;
4090                }
4091                final boolean trIsDocument = trIntent != null && trIntent.isDocument();
4092                if (document && trIsDocument) {
4093                    // These are the same document activity (not necessarily the same doc).
4094                    if (maxRecents > 0) {
4095                        --maxRecents;
4096                        continue;
4097                    }
4098                    // Hit the maximum number of documents for this task. Fall through
4099                    // and remove this document from recents.
4100                } else if (document || trIsDocument) {
4101                    // Only one of these is a document. Not the droid we're looking for.
4102                    continue;
4103                }
4104            }
4105
4106            if (!doTrim) {
4107                // If the caller is not actually asking for a trim, just tell them we reached
4108                // a point where the trim would happen.
4109                return i;
4110            }
4111
4112            // Either task and tr are the same or, their affinities match or their intents match
4113            // and neither of them is a document, or they are documents using the same activity
4114            // and their maxRecents has been reached.
4115            tr.disposeThumbnail();
4116            mRecentTasks.remove(i);
4117            if (task != tr) {
4118                tr.removedFromRecents(mTaskPersister);
4119            }
4120            i--;
4121            N--;
4122            if (task.intent == null) {
4123                // If the new recent task we are adding is not fully
4124                // specified, then replace it with the existing recent task.
4125                task = tr;
4126            }
4127            notifyTaskPersisterLocked(tr, false);
4128        }
4129
4130        return -1;
4131    }
4132
4133    @Override
4134    public void reportActivityFullyDrawn(IBinder token) {
4135        synchronized (this) {
4136            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4137            if (r == null) {
4138                return;
4139            }
4140            r.reportFullyDrawnLocked();
4141        }
4142    }
4143
4144    @Override
4145    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4146        synchronized (this) {
4147            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4148            if (r == null) {
4149                return;
4150            }
4151            final long origId = Binder.clearCallingIdentity();
4152            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4153            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4154                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4155            if (config != null) {
4156                r.frozenBeforeDestroy = true;
4157                if (!updateConfigurationLocked(config, r, false, false)) {
4158                    mStackSupervisor.resumeTopActivitiesLocked();
4159                }
4160            }
4161            Binder.restoreCallingIdentity(origId);
4162        }
4163    }
4164
4165    @Override
4166    public int getRequestedOrientation(IBinder token) {
4167        synchronized (this) {
4168            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4169            if (r == null) {
4170                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4171            }
4172            return mWindowManager.getAppOrientation(r.appToken);
4173        }
4174    }
4175
4176    /**
4177     * This is the internal entry point for handling Activity.finish().
4178     *
4179     * @param token The Binder token referencing the Activity we want to finish.
4180     * @param resultCode Result code, if any, from this Activity.
4181     * @param resultData Result data (Intent), if any, from this Activity.
4182     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
4183     *            the root Activity in the task.
4184     *
4185     * @return Returns true if the activity successfully finished, or false if it is still running.
4186     */
4187    @Override
4188    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4189            boolean finishTask) {
4190        // Refuse possible leaked file descriptors
4191        if (resultData != null && resultData.hasFileDescriptors() == true) {
4192            throw new IllegalArgumentException("File descriptors passed in Intent");
4193        }
4194
4195        synchronized(this) {
4196            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4197            if (r == null) {
4198                return true;
4199            }
4200            // Keep track of the root activity of the task before we finish it
4201            TaskRecord tr = r.task;
4202            ActivityRecord rootR = tr.getRootActivity();
4203            if (rootR == null) {
4204                Slog.w(TAG, "Finishing task with all activities already finished");
4205            }
4206            // Do not allow task to finish in Lock Task mode.
4207            if (tr == mStackSupervisor.mLockTaskModeTask) {
4208                if (rootR == r) {
4209                    Slog.i(TAG, "Not finishing task in lock task mode");
4210                    mStackSupervisor.showLockTaskToast();
4211                    return false;
4212                }
4213            }
4214            if (mController != null) {
4215                // Find the first activity that is not finishing.
4216                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4217                if (next != null) {
4218                    // ask watcher if this is allowed
4219                    boolean resumeOK = true;
4220                    try {
4221                        resumeOK = mController.activityResuming(next.packageName);
4222                    } catch (RemoteException e) {
4223                        mController = null;
4224                        Watchdog.getInstance().setActivityController(null);
4225                    }
4226
4227                    if (!resumeOK) {
4228                        Slog.i(TAG, "Not finishing activity because controller resumed");
4229                        return false;
4230                    }
4231                }
4232            }
4233            final long origId = Binder.clearCallingIdentity();
4234            try {
4235                boolean res;
4236                if (finishTask && r == rootR) {
4237                    // If requested, remove the task that is associated to this activity only if it
4238                    // was the root activity in the task. The result code and data is ignored
4239                    // because we don't support returning them across task boundaries.
4240                    res = removeTaskByIdLocked(tr.taskId, false);
4241                    if (!res) {
4242                        Slog.i(TAG, "Removing task failed to finish activity");
4243                    }
4244                } else {
4245                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4246                            resultData, "app-request", true);
4247                    if (!res) {
4248                        Slog.i(TAG, "Failed to finish by app-request");
4249                    }
4250                }
4251                return res;
4252            } finally {
4253                Binder.restoreCallingIdentity(origId);
4254            }
4255        }
4256    }
4257
4258    @Override
4259    public final void finishHeavyWeightApp() {
4260        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4261                != PackageManager.PERMISSION_GRANTED) {
4262            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4263                    + Binder.getCallingPid()
4264                    + ", uid=" + Binder.getCallingUid()
4265                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4266            Slog.w(TAG, msg);
4267            throw new SecurityException(msg);
4268        }
4269
4270        synchronized(this) {
4271            if (mHeavyWeightProcess == null) {
4272                return;
4273            }
4274
4275            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
4276                    mHeavyWeightProcess.activities);
4277            for (int i=0; i<activities.size(); i++) {
4278                ActivityRecord r = activities.get(i);
4279                if (!r.finishing) {
4280                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4281                            null, "finish-heavy", true);
4282                }
4283            }
4284
4285            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4286                    mHeavyWeightProcess.userId, 0));
4287            mHeavyWeightProcess = null;
4288        }
4289    }
4290
4291    @Override
4292    public void crashApplication(int uid, int initialPid, String packageName,
4293            String message) {
4294        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4295                != PackageManager.PERMISSION_GRANTED) {
4296            String msg = "Permission Denial: crashApplication() from pid="
4297                    + Binder.getCallingPid()
4298                    + ", uid=" + Binder.getCallingUid()
4299                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4300            Slog.w(TAG, msg);
4301            throw new SecurityException(msg);
4302        }
4303
4304        synchronized(this) {
4305            ProcessRecord proc = null;
4306
4307            // Figure out which process to kill.  We don't trust that initialPid
4308            // still has any relation to current pids, so must scan through the
4309            // list.
4310            synchronized (mPidsSelfLocked) {
4311                for (int i=0; i<mPidsSelfLocked.size(); i++) {
4312                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
4313                    if (p.uid != uid) {
4314                        continue;
4315                    }
4316                    if (p.pid == initialPid) {
4317                        proc = p;
4318                        break;
4319                    }
4320                    if (p.pkgList.containsKey(packageName)) {
4321                        proc = p;
4322                    }
4323                }
4324            }
4325
4326            if (proc == null) {
4327                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
4328                        + " initialPid=" + initialPid
4329                        + " packageName=" + packageName);
4330                return;
4331            }
4332
4333            if (proc.thread != null) {
4334                if (proc.pid == Process.myPid()) {
4335                    Log.w(TAG, "crashApplication: trying to crash self!");
4336                    return;
4337                }
4338                long ident = Binder.clearCallingIdentity();
4339                try {
4340                    proc.thread.scheduleCrash(message);
4341                } catch (RemoteException e) {
4342                }
4343                Binder.restoreCallingIdentity(ident);
4344            }
4345        }
4346    }
4347
4348    @Override
4349    public final void finishSubActivity(IBinder token, String resultWho,
4350            int requestCode) {
4351        synchronized(this) {
4352            final long origId = Binder.clearCallingIdentity();
4353            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4354            if (r != null) {
4355                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4356            }
4357            Binder.restoreCallingIdentity(origId);
4358        }
4359    }
4360
4361    @Override
4362    public boolean finishActivityAffinity(IBinder token) {
4363        synchronized(this) {
4364            final long origId = Binder.clearCallingIdentity();
4365            try {
4366                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4367
4368                ActivityRecord rootR = r.task.getRootActivity();
4369                // Do not allow task to finish in Lock Task mode.
4370                if (r.task == mStackSupervisor.mLockTaskModeTask) {
4371                    if (rootR == r) {
4372                        mStackSupervisor.showLockTaskToast();
4373                        return false;
4374                    }
4375                }
4376                boolean res = false;
4377                if (r != null) {
4378                    res = r.task.stack.finishActivityAffinityLocked(r);
4379                }
4380                return res;
4381            } finally {
4382                Binder.restoreCallingIdentity(origId);
4383            }
4384        }
4385    }
4386
4387    @Override
4388    public void finishVoiceTask(IVoiceInteractionSession session) {
4389        synchronized(this) {
4390            final long origId = Binder.clearCallingIdentity();
4391            try {
4392                mStackSupervisor.finishVoiceTask(session);
4393            } finally {
4394                Binder.restoreCallingIdentity(origId);
4395            }
4396        }
4397
4398    }
4399
4400    @Override
4401    public boolean releaseActivityInstance(IBinder token) {
4402        synchronized(this) {
4403            final long origId = Binder.clearCallingIdentity();
4404            try {
4405                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4406                if (r.task == null || r.task.stack == null) {
4407                    return false;
4408                }
4409                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4410            } finally {
4411                Binder.restoreCallingIdentity(origId);
4412            }
4413        }
4414    }
4415
4416    @Override
4417    public void releaseSomeActivities(IApplicationThread appInt) {
4418        synchronized(this) {
4419            final long origId = Binder.clearCallingIdentity();
4420            try {
4421                ProcessRecord app = getRecordForAppLocked(appInt);
4422                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4423            } finally {
4424                Binder.restoreCallingIdentity(origId);
4425            }
4426        }
4427    }
4428
4429    @Override
4430    public boolean willActivityBeVisible(IBinder token) {
4431        synchronized(this) {
4432            ActivityStack stack = ActivityRecord.getStackLocked(token);
4433            if (stack != null) {
4434                return stack.willActivityBeVisibleLocked(token);
4435            }
4436            return false;
4437        }
4438    }
4439
4440    @Override
4441    public void overridePendingTransition(IBinder token, String packageName,
4442            int enterAnim, int exitAnim) {
4443        synchronized(this) {
4444            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4445            if (self == null) {
4446                return;
4447            }
4448
4449            final long origId = Binder.clearCallingIdentity();
4450
4451            if (self.state == ActivityState.RESUMED
4452                    || self.state == ActivityState.PAUSING) {
4453                mWindowManager.overridePendingAppTransition(packageName,
4454                        enterAnim, exitAnim, null);
4455            }
4456
4457            Binder.restoreCallingIdentity(origId);
4458        }
4459    }
4460
4461    /**
4462     * Main function for removing an existing process from the activity manager
4463     * as a result of that process going away.  Clears out all connections
4464     * to the process.
4465     */
4466    private final void handleAppDiedLocked(ProcessRecord app,
4467            boolean restarting, boolean allowRestart) {
4468        int pid = app.pid;
4469        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4470        if (!kept && !restarting) {
4471            removeLruProcessLocked(app);
4472            if (pid > 0) {
4473                ProcessList.remove(pid);
4474            }
4475        }
4476
4477        if (mProfileProc == app) {
4478            clearProfilerLocked();
4479        }
4480
4481        // Remove this application's activities from active lists.
4482        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4483
4484        app.activities.clear();
4485
4486        if (app.instrumentationClass != null) {
4487            Slog.w(TAG, "Crash of app " + app.processName
4488                  + " running instrumentation " + app.instrumentationClass);
4489            Bundle info = new Bundle();
4490            info.putString("shortMsg", "Process crashed.");
4491            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4492        }
4493
4494        if (!restarting) {
4495            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
4496                // If there was nothing to resume, and we are not already
4497                // restarting this process, but there is a visible activity that
4498                // is hosted by the process...  then make sure all visible
4499                // activities are running, taking care of restarting this
4500                // process.
4501                if (hasVisibleActivities) {
4502                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
4503                }
4504            }
4505        }
4506    }
4507
4508    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4509        IBinder threadBinder = thread.asBinder();
4510        // Find the application record.
4511        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4512            ProcessRecord rec = mLruProcesses.get(i);
4513            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4514                return i;
4515            }
4516        }
4517        return -1;
4518    }
4519
4520    final ProcessRecord getRecordForAppLocked(
4521            IApplicationThread thread) {
4522        if (thread == null) {
4523            return null;
4524        }
4525
4526        int appIndex = getLRURecordIndexForAppLocked(thread);
4527        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4528    }
4529
4530    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4531        // If there are no longer any background processes running,
4532        // and the app that died was not running instrumentation,
4533        // then tell everyone we are now low on memory.
4534        boolean haveBg = false;
4535        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4536            ProcessRecord rec = mLruProcesses.get(i);
4537            if (rec.thread != null
4538                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4539                haveBg = true;
4540                break;
4541            }
4542        }
4543
4544        if (!haveBg) {
4545            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4546            if (doReport) {
4547                long now = SystemClock.uptimeMillis();
4548                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4549                    doReport = false;
4550                } else {
4551                    mLastMemUsageReportTime = now;
4552                }
4553            }
4554            final ArrayList<ProcessMemInfo> memInfos
4555                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4556            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4557            long now = SystemClock.uptimeMillis();
4558            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4559                ProcessRecord rec = mLruProcesses.get(i);
4560                if (rec == dyingProc || rec.thread == null) {
4561                    continue;
4562                }
4563                if (doReport) {
4564                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4565                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4566                }
4567                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4568                    // The low memory report is overriding any current
4569                    // state for a GC request.  Make sure to do
4570                    // heavy/important/visible/foreground processes first.
4571                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4572                        rec.lastRequestedGc = 0;
4573                    } else {
4574                        rec.lastRequestedGc = rec.lastLowMemory;
4575                    }
4576                    rec.reportLowMemory = true;
4577                    rec.lastLowMemory = now;
4578                    mProcessesToGc.remove(rec);
4579                    addProcessToGcListLocked(rec);
4580                }
4581            }
4582            if (doReport) {
4583                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4584                mHandler.sendMessage(msg);
4585            }
4586            scheduleAppGcsLocked();
4587        }
4588    }
4589
4590    final void appDiedLocked(ProcessRecord app) {
4591       appDiedLocked(app, app.pid, app.thread);
4592    }
4593
4594    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread) {
4595        // First check if this ProcessRecord is actually active for the pid.
4596        synchronized (mPidsSelfLocked) {
4597            ProcessRecord curProc = mPidsSelfLocked.get(pid);
4598            if (curProc != app) {
4599                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
4600                return;
4601            }
4602        }
4603
4604        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4605        synchronized (stats) {
4606            stats.noteProcessDiedLocked(app.info.uid, pid);
4607        }
4608
4609        Process.killProcessQuiet(pid);
4610        Process.killProcessGroup(app.info.uid, pid);
4611        app.killed = true;
4612
4613        // Clean up already done if the process has been re-started.
4614        if (app.pid == pid && app.thread != null &&
4615                app.thread.asBinder() == thread.asBinder()) {
4616            boolean doLowMem = app.instrumentationClass == null;
4617            boolean doOomAdj = doLowMem;
4618            if (!app.killedByAm) {
4619                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4620                        + ") has died");
4621                mAllowLowerMemLevel = true;
4622            } else {
4623                // Note that we always want to do oom adj to update our state with the
4624                // new number of procs.
4625                mAllowLowerMemLevel = false;
4626                doLowMem = false;
4627            }
4628            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4629            if (DEBUG_CLEANUP) Slog.v(
4630                TAG, "Dying app: " + app + ", pid: " + pid
4631                + ", thread: " + thread.asBinder());
4632            handleAppDiedLocked(app, false, true);
4633
4634            if (doOomAdj) {
4635                updateOomAdjLocked();
4636            }
4637            if (doLowMem) {
4638                doLowMemReportIfNeededLocked(app);
4639            }
4640        } else if (app.pid != pid) {
4641            // A new process has already been started.
4642            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4643                    + ") has died and restarted (pid " + app.pid + ").");
4644            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4645        } else if (DEBUG_PROCESSES) {
4646            Slog.d(TAG, "Received spurious death notification for thread "
4647                    + thread.asBinder());
4648        }
4649    }
4650
4651    /**
4652     * If a stack trace dump file is configured, dump process stack traces.
4653     * @param clearTraces causes the dump file to be erased prior to the new
4654     *    traces being written, if true; when false, the new traces will be
4655     *    appended to any existing file content.
4656     * @param firstPids of dalvik VM processes to dump stack traces for first
4657     * @param lastPids of dalvik VM processes to dump stack traces for last
4658     * @param nativeProcs optional list of native process names to dump stack crawls
4659     * @return file containing stack traces, or null if no dump file is configured
4660     */
4661    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4662            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4663        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4664        if (tracesPath == null || tracesPath.length() == 0) {
4665            return null;
4666        }
4667
4668        File tracesFile = new File(tracesPath);
4669        try {
4670            File tracesDir = tracesFile.getParentFile();
4671            if (!tracesDir.exists()) {
4672                tracesDir.mkdirs();
4673                if (!SELinux.restorecon(tracesDir)) {
4674                    return null;
4675                }
4676            }
4677            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4678
4679            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4680            tracesFile.createNewFile();
4681            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4682        } catch (IOException e) {
4683            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4684            return null;
4685        }
4686
4687        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4688        return tracesFile;
4689    }
4690
4691    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4692            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4693        // Use a FileObserver to detect when traces finish writing.
4694        // The order of traces is considered important to maintain for legibility.
4695        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4696            @Override
4697            public synchronized void onEvent(int event, String path) { notify(); }
4698        };
4699
4700        try {
4701            observer.startWatching();
4702
4703            // First collect all of the stacks of the most important pids.
4704            if (firstPids != null) {
4705                try {
4706                    int num = firstPids.size();
4707                    for (int i = 0; i < num; i++) {
4708                        synchronized (observer) {
4709                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4710                            observer.wait(200);  // Wait for write-close, give up after 200msec
4711                        }
4712                    }
4713                } catch (InterruptedException e) {
4714                    Slog.wtf(TAG, e);
4715                }
4716            }
4717
4718            // Next collect the stacks of the native pids
4719            if (nativeProcs != null) {
4720                int[] pids = Process.getPidsForCommands(nativeProcs);
4721                if (pids != null) {
4722                    for (int pid : pids) {
4723                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4724                    }
4725                }
4726            }
4727
4728            // Lastly, measure CPU usage.
4729            if (processCpuTracker != null) {
4730                processCpuTracker.init();
4731                System.gc();
4732                processCpuTracker.update();
4733                try {
4734                    synchronized (processCpuTracker) {
4735                        processCpuTracker.wait(500); // measure over 1/2 second.
4736                    }
4737                } catch (InterruptedException e) {
4738                }
4739                processCpuTracker.update();
4740
4741                // We'll take the stack crawls of just the top apps using CPU.
4742                final int N = processCpuTracker.countWorkingStats();
4743                int numProcs = 0;
4744                for (int i=0; i<N && numProcs<5; i++) {
4745                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4746                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4747                        numProcs++;
4748                        try {
4749                            synchronized (observer) {
4750                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4751                                observer.wait(200);  // Wait for write-close, give up after 200msec
4752                            }
4753                        } catch (InterruptedException e) {
4754                            Slog.wtf(TAG, e);
4755                        }
4756
4757                    }
4758                }
4759            }
4760        } finally {
4761            observer.stopWatching();
4762        }
4763    }
4764
4765    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4766        if (true || IS_USER_BUILD) {
4767            return;
4768        }
4769        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4770        if (tracesPath == null || tracesPath.length() == 0) {
4771            return;
4772        }
4773
4774        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4775        StrictMode.allowThreadDiskWrites();
4776        try {
4777            final File tracesFile = new File(tracesPath);
4778            final File tracesDir = tracesFile.getParentFile();
4779            final File tracesTmp = new File(tracesDir, "__tmp__");
4780            try {
4781                if (!tracesDir.exists()) {
4782                    tracesDir.mkdirs();
4783                    if (!SELinux.restorecon(tracesDir.getPath())) {
4784                        return;
4785                    }
4786                }
4787                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4788
4789                if (tracesFile.exists()) {
4790                    tracesTmp.delete();
4791                    tracesFile.renameTo(tracesTmp);
4792                }
4793                StringBuilder sb = new StringBuilder();
4794                Time tobj = new Time();
4795                tobj.set(System.currentTimeMillis());
4796                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4797                sb.append(": ");
4798                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4799                sb.append(" since ");
4800                sb.append(msg);
4801                FileOutputStream fos = new FileOutputStream(tracesFile);
4802                fos.write(sb.toString().getBytes());
4803                if (app == null) {
4804                    fos.write("\n*** No application process!".getBytes());
4805                }
4806                fos.close();
4807                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4808            } catch (IOException e) {
4809                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4810                return;
4811            }
4812
4813            if (app != null) {
4814                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4815                firstPids.add(app.pid);
4816                dumpStackTraces(tracesPath, firstPids, null, null, null);
4817            }
4818
4819            File lastTracesFile = null;
4820            File curTracesFile = null;
4821            for (int i=9; i>=0; i--) {
4822                String name = String.format(Locale.US, "slow%02d.txt", i);
4823                curTracesFile = new File(tracesDir, name);
4824                if (curTracesFile.exists()) {
4825                    if (lastTracesFile != null) {
4826                        curTracesFile.renameTo(lastTracesFile);
4827                    } else {
4828                        curTracesFile.delete();
4829                    }
4830                }
4831                lastTracesFile = curTracesFile;
4832            }
4833            tracesFile.renameTo(curTracesFile);
4834            if (tracesTmp.exists()) {
4835                tracesTmp.renameTo(tracesFile);
4836            }
4837        } finally {
4838            StrictMode.setThreadPolicy(oldPolicy);
4839        }
4840    }
4841
4842    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4843            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4844        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4845        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4846
4847        if (mController != null) {
4848            try {
4849                // 0 == continue, -1 = kill process immediately
4850                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4851                if (res < 0 && app.pid != MY_PID) {
4852                    app.kill("anr", true);
4853                }
4854            } catch (RemoteException e) {
4855                mController = null;
4856                Watchdog.getInstance().setActivityController(null);
4857            }
4858        }
4859
4860        long anrTime = SystemClock.uptimeMillis();
4861        if (MONITOR_CPU_USAGE) {
4862            updateCpuStatsNow();
4863        }
4864
4865        synchronized (this) {
4866            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4867            if (mShuttingDown) {
4868                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4869                return;
4870            } else if (app.notResponding) {
4871                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4872                return;
4873            } else if (app.crashing) {
4874                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4875                return;
4876            }
4877
4878            // In case we come through here for the same app before completing
4879            // this one, mark as anring now so we will bail out.
4880            app.notResponding = true;
4881
4882            // Log the ANR to the event log.
4883            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4884                    app.processName, app.info.flags, annotation);
4885
4886            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4887            firstPids.add(app.pid);
4888
4889            int parentPid = app.pid;
4890            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4891            if (parentPid != app.pid) firstPids.add(parentPid);
4892
4893            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4894
4895            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4896                ProcessRecord r = mLruProcesses.get(i);
4897                if (r != null && r.thread != null) {
4898                    int pid = r.pid;
4899                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4900                        if (r.persistent) {
4901                            firstPids.add(pid);
4902                        } else {
4903                            lastPids.put(pid, Boolean.TRUE);
4904                        }
4905                    }
4906                }
4907            }
4908        }
4909
4910        // Log the ANR to the main log.
4911        StringBuilder info = new StringBuilder();
4912        info.setLength(0);
4913        info.append("ANR in ").append(app.processName);
4914        if (activity != null && activity.shortComponentName != null) {
4915            info.append(" (").append(activity.shortComponentName).append(")");
4916        }
4917        info.append("\n");
4918        info.append("PID: ").append(app.pid).append("\n");
4919        if (annotation != null) {
4920            info.append("Reason: ").append(annotation).append("\n");
4921        }
4922        if (parent != null && parent != activity) {
4923            info.append("Parent: ").append(parent.shortComponentName).append("\n");
4924        }
4925
4926        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4927
4928        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4929                NATIVE_STACKS_OF_INTEREST);
4930
4931        String cpuInfo = null;
4932        if (MONITOR_CPU_USAGE) {
4933            updateCpuStatsNow();
4934            synchronized (mProcessCpuTracker) {
4935                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4936            }
4937            info.append(processCpuTracker.printCurrentLoad());
4938            info.append(cpuInfo);
4939        }
4940
4941        info.append(processCpuTracker.printCurrentState(anrTime));
4942
4943        Slog.e(TAG, info.toString());
4944        if (tracesFile == null) {
4945            // There is no trace file, so dump (only) the alleged culprit's threads to the log
4946            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4947        }
4948
4949        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
4950                cpuInfo, tracesFile, null);
4951
4952        if (mController != null) {
4953            try {
4954                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
4955                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
4956                if (res != 0) {
4957                    if (res < 0 && app.pid != MY_PID) {
4958                        app.kill("anr", true);
4959                    } else {
4960                        synchronized (this) {
4961                            mServices.scheduleServiceTimeoutLocked(app);
4962                        }
4963                    }
4964                    return;
4965                }
4966            } catch (RemoteException e) {
4967                mController = null;
4968                Watchdog.getInstance().setActivityController(null);
4969            }
4970        }
4971
4972        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
4973        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
4974                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
4975
4976        synchronized (this) {
4977            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
4978                app.kill("bg anr", true);
4979                return;
4980            }
4981
4982            // Set the app's notResponding state, and look up the errorReportReceiver
4983            makeAppNotRespondingLocked(app,
4984                    activity != null ? activity.shortComponentName : null,
4985                    annotation != null ? "ANR " + annotation : "ANR",
4986                    info.toString());
4987
4988            // Bring up the infamous App Not Responding dialog
4989            Message msg = Message.obtain();
4990            HashMap<String, Object> map = new HashMap<String, Object>();
4991            msg.what = SHOW_NOT_RESPONDING_MSG;
4992            msg.obj = map;
4993            msg.arg1 = aboveSystem ? 1 : 0;
4994            map.put("app", app);
4995            if (activity != null) {
4996                map.put("activity", activity);
4997            }
4998
4999            mHandler.sendMessage(msg);
5000        }
5001    }
5002
5003    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5004        if (!mLaunchWarningShown) {
5005            mLaunchWarningShown = true;
5006            mHandler.post(new Runnable() {
5007                @Override
5008                public void run() {
5009                    synchronized (ActivityManagerService.this) {
5010                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5011                        d.show();
5012                        mHandler.postDelayed(new Runnable() {
5013                            @Override
5014                            public void run() {
5015                                synchronized (ActivityManagerService.this) {
5016                                    d.dismiss();
5017                                    mLaunchWarningShown = false;
5018                                }
5019                            }
5020                        }, 4000);
5021                    }
5022                }
5023            });
5024        }
5025    }
5026
5027    @Override
5028    public boolean clearApplicationUserData(final String packageName,
5029            final IPackageDataObserver observer, int userId) {
5030        enforceNotIsolatedCaller("clearApplicationUserData");
5031        int uid = Binder.getCallingUid();
5032        int pid = Binder.getCallingPid();
5033        userId = handleIncomingUser(pid, uid,
5034                userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5035        long callingId = Binder.clearCallingIdentity();
5036        try {
5037            IPackageManager pm = AppGlobals.getPackageManager();
5038            int pkgUid = -1;
5039            synchronized(this) {
5040                try {
5041                    pkgUid = pm.getPackageUid(packageName, userId);
5042                } catch (RemoteException e) {
5043                }
5044                if (pkgUid == -1) {
5045                    Slog.w(TAG, "Invalid packageName: " + packageName);
5046                    if (observer != null) {
5047                        try {
5048                            observer.onRemoveCompleted(packageName, false);
5049                        } catch (RemoteException e) {
5050                            Slog.i(TAG, "Observer no longer exists.");
5051                        }
5052                    }
5053                    return false;
5054                }
5055                if (uid == pkgUid || checkComponentPermission(
5056                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5057                        pid, uid, -1, true)
5058                        == PackageManager.PERMISSION_GRANTED) {
5059                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5060                } else {
5061                    throw new SecurityException("PID " + pid + " does not have permission "
5062                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5063                                    + " of package " + packageName);
5064                }
5065
5066                // Remove all tasks match the cleared application package and user
5067                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5068                    final TaskRecord tr = mRecentTasks.get(i);
5069                    final String taskPackageName =
5070                            tr.getBaseIntent().getComponent().getPackageName();
5071                    if (tr.userId != userId) continue;
5072                    if (!taskPackageName.equals(packageName)) continue;
5073                    removeTaskByIdLocked(tr.taskId, false);
5074                }
5075            }
5076
5077            try {
5078                // Clear application user data
5079                pm.clearApplicationUserData(packageName, observer, userId);
5080
5081                synchronized(this) {
5082                    // Remove all permissions granted from/to this package
5083                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5084                }
5085
5086                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5087                        Uri.fromParts("package", packageName, null));
5088                intent.putExtra(Intent.EXTRA_UID, pkgUid);
5089                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5090                        null, null, 0, null, null, null, false, false, userId);
5091            } catch (RemoteException e) {
5092            }
5093        } finally {
5094            Binder.restoreCallingIdentity(callingId);
5095        }
5096        return true;
5097    }
5098
5099    @Override
5100    public void killBackgroundProcesses(final String packageName, int userId) {
5101        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5102                != PackageManager.PERMISSION_GRANTED &&
5103                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5104                        != PackageManager.PERMISSION_GRANTED) {
5105            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5106                    + Binder.getCallingPid()
5107                    + ", uid=" + Binder.getCallingUid()
5108                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5109            Slog.w(TAG, msg);
5110            throw new SecurityException(msg);
5111        }
5112
5113        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5114                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5115        long callingId = Binder.clearCallingIdentity();
5116        try {
5117            IPackageManager pm = AppGlobals.getPackageManager();
5118            synchronized(this) {
5119                int appId = -1;
5120                try {
5121                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
5122                } catch (RemoteException e) {
5123                }
5124                if (appId == -1) {
5125                    Slog.w(TAG, "Invalid packageName: " + packageName);
5126                    return;
5127                }
5128                killPackageProcessesLocked(packageName, appId, userId,
5129                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5130            }
5131        } finally {
5132            Binder.restoreCallingIdentity(callingId);
5133        }
5134    }
5135
5136    @Override
5137    public void killAllBackgroundProcesses() {
5138        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5139                != PackageManager.PERMISSION_GRANTED) {
5140            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5141                    + Binder.getCallingPid()
5142                    + ", uid=" + Binder.getCallingUid()
5143                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5144            Slog.w(TAG, msg);
5145            throw new SecurityException(msg);
5146        }
5147
5148        long callingId = Binder.clearCallingIdentity();
5149        try {
5150            synchronized(this) {
5151                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5152                final int NP = mProcessNames.getMap().size();
5153                for (int ip=0; ip<NP; ip++) {
5154                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5155                    final int NA = apps.size();
5156                    for (int ia=0; ia<NA; ia++) {
5157                        ProcessRecord app = apps.valueAt(ia);
5158                        if (app.persistent) {
5159                            // we don't kill persistent processes
5160                            continue;
5161                        }
5162                        if (app.removed) {
5163                            procs.add(app);
5164                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5165                            app.removed = true;
5166                            procs.add(app);
5167                        }
5168                    }
5169                }
5170
5171                int N = procs.size();
5172                for (int i=0; i<N; i++) {
5173                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5174                }
5175                mAllowLowerMemLevel = true;
5176                updateOomAdjLocked();
5177                doLowMemReportIfNeededLocked(null);
5178            }
5179        } finally {
5180            Binder.restoreCallingIdentity(callingId);
5181        }
5182    }
5183
5184    @Override
5185    public void forceStopPackage(final String packageName, int userId) {
5186        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5187                != PackageManager.PERMISSION_GRANTED) {
5188            String msg = "Permission Denial: forceStopPackage() from pid="
5189                    + Binder.getCallingPid()
5190                    + ", uid=" + Binder.getCallingUid()
5191                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5192            Slog.w(TAG, msg);
5193            throw new SecurityException(msg);
5194        }
5195        final int callingPid = Binder.getCallingPid();
5196        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
5197                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5198        long callingId = Binder.clearCallingIdentity();
5199        try {
5200            IPackageManager pm = AppGlobals.getPackageManager();
5201            synchronized(this) {
5202                int[] users = userId == UserHandle.USER_ALL
5203                        ? getUsersLocked() : new int[] { userId };
5204                for (int user : users) {
5205                    int pkgUid = -1;
5206                    try {
5207                        pkgUid = pm.getPackageUid(packageName, user);
5208                    } catch (RemoteException e) {
5209                    }
5210                    if (pkgUid == -1) {
5211                        Slog.w(TAG, "Invalid packageName: " + packageName);
5212                        continue;
5213                    }
5214                    try {
5215                        pm.setPackageStoppedState(packageName, true, user);
5216                    } catch (RemoteException e) {
5217                    } catch (IllegalArgumentException e) {
5218                        Slog.w(TAG, "Failed trying to unstop package "
5219                                + packageName + ": " + e);
5220                    }
5221                    if (isUserRunningLocked(user, false)) {
5222                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5223                    }
5224                }
5225            }
5226        } finally {
5227            Binder.restoreCallingIdentity(callingId);
5228        }
5229    }
5230
5231    @Override
5232    public void addPackageDependency(String packageName) {
5233        synchronized (this) {
5234            int callingPid = Binder.getCallingPid();
5235            if (callingPid == Process.myPid()) {
5236                //  Yeah, um, no.
5237                Slog.w(TAG, "Can't addPackageDependency on system process");
5238                return;
5239            }
5240            ProcessRecord proc;
5241            synchronized (mPidsSelfLocked) {
5242                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5243            }
5244            if (proc != null) {
5245                if (proc.pkgDeps == null) {
5246                    proc.pkgDeps = new ArraySet<String>(1);
5247                }
5248                proc.pkgDeps.add(packageName);
5249            }
5250        }
5251    }
5252
5253    /*
5254     * The pkg name and app id have to be specified.
5255     */
5256    @Override
5257    public void killApplicationWithAppId(String pkg, int appid, String reason) {
5258        if (pkg == null) {
5259            return;
5260        }
5261        // Make sure the uid is valid.
5262        if (appid < 0) {
5263            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5264            return;
5265        }
5266        int callerUid = Binder.getCallingUid();
5267        // Only the system server can kill an application
5268        if (callerUid == Process.SYSTEM_UID) {
5269            // Post an aysnc message to kill the application
5270            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5271            msg.arg1 = appid;
5272            msg.arg2 = 0;
5273            Bundle bundle = new Bundle();
5274            bundle.putString("pkg", pkg);
5275            bundle.putString("reason", reason);
5276            msg.obj = bundle;
5277            mHandler.sendMessage(msg);
5278        } else {
5279            throw new SecurityException(callerUid + " cannot kill pkg: " +
5280                    pkg);
5281        }
5282    }
5283
5284    @Override
5285    public void closeSystemDialogs(String reason) {
5286        enforceNotIsolatedCaller("closeSystemDialogs");
5287
5288        final int pid = Binder.getCallingPid();
5289        final int uid = Binder.getCallingUid();
5290        final long origId = Binder.clearCallingIdentity();
5291        try {
5292            synchronized (this) {
5293                // Only allow this from foreground processes, so that background
5294                // applications can't abuse it to prevent system UI from being shown.
5295                if (uid >= Process.FIRST_APPLICATION_UID) {
5296                    ProcessRecord proc;
5297                    synchronized (mPidsSelfLocked) {
5298                        proc = mPidsSelfLocked.get(pid);
5299                    }
5300                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5301                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5302                                + " from background process " + proc);
5303                        return;
5304                    }
5305                }
5306                closeSystemDialogsLocked(reason);
5307            }
5308        } finally {
5309            Binder.restoreCallingIdentity(origId);
5310        }
5311    }
5312
5313    void closeSystemDialogsLocked(String reason) {
5314        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5315        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5316                | Intent.FLAG_RECEIVER_FOREGROUND);
5317        if (reason != null) {
5318            intent.putExtra("reason", reason);
5319        }
5320        mWindowManager.closeSystemDialogs(reason);
5321
5322        mStackSupervisor.closeSystemDialogsLocked();
5323
5324        broadcastIntentLocked(null, null, intent, null,
5325                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
5326                Process.SYSTEM_UID, UserHandle.USER_ALL);
5327    }
5328
5329    @Override
5330    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5331        enforceNotIsolatedCaller("getProcessMemoryInfo");
5332        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5333        for (int i=pids.length-1; i>=0; i--) {
5334            ProcessRecord proc;
5335            int oomAdj;
5336            synchronized (this) {
5337                synchronized (mPidsSelfLocked) {
5338                    proc = mPidsSelfLocked.get(pids[i]);
5339                    oomAdj = proc != null ? proc.setAdj : 0;
5340                }
5341            }
5342            infos[i] = new Debug.MemoryInfo();
5343            Debug.getMemoryInfo(pids[i], infos[i]);
5344            if (proc != null) {
5345                synchronized (this) {
5346                    if (proc.thread != null && proc.setAdj == oomAdj) {
5347                        // Record this for posterity if the process has been stable.
5348                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5349                                infos[i].getTotalUss(), false, proc.pkgList);
5350                    }
5351                }
5352            }
5353        }
5354        return infos;
5355    }
5356
5357    @Override
5358    public long[] getProcessPss(int[] pids) {
5359        enforceNotIsolatedCaller("getProcessPss");
5360        long[] pss = new long[pids.length];
5361        for (int i=pids.length-1; i>=0; i--) {
5362            ProcessRecord proc;
5363            int oomAdj;
5364            synchronized (this) {
5365                synchronized (mPidsSelfLocked) {
5366                    proc = mPidsSelfLocked.get(pids[i]);
5367                    oomAdj = proc != null ? proc.setAdj : 0;
5368                }
5369            }
5370            long[] tmpUss = new long[1];
5371            pss[i] = Debug.getPss(pids[i], tmpUss);
5372            if (proc != null) {
5373                synchronized (this) {
5374                    if (proc.thread != null && proc.setAdj == oomAdj) {
5375                        // Record this for posterity if the process has been stable.
5376                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5377                    }
5378                }
5379            }
5380        }
5381        return pss;
5382    }
5383
5384    @Override
5385    public void killApplicationProcess(String processName, int uid) {
5386        if (processName == null) {
5387            return;
5388        }
5389
5390        int callerUid = Binder.getCallingUid();
5391        // Only the system server can kill an application
5392        if (callerUid == Process.SYSTEM_UID) {
5393            synchronized (this) {
5394                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5395                if (app != null && app.thread != null) {
5396                    try {
5397                        app.thread.scheduleSuicide();
5398                    } catch (RemoteException e) {
5399                        // If the other end already died, then our work here is done.
5400                    }
5401                } else {
5402                    Slog.w(TAG, "Process/uid not found attempting kill of "
5403                            + processName + " / " + uid);
5404                }
5405            }
5406        } else {
5407            throw new SecurityException(callerUid + " cannot kill app process: " +
5408                    processName);
5409        }
5410    }
5411
5412    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5413        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5414                false, true, false, false, UserHandle.getUserId(uid), reason);
5415        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5416                Uri.fromParts("package", packageName, null));
5417        if (!mProcessesReady) {
5418            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5419                    | Intent.FLAG_RECEIVER_FOREGROUND);
5420        }
5421        intent.putExtra(Intent.EXTRA_UID, uid);
5422        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5423        broadcastIntentLocked(null, null, intent,
5424                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5425                false, false,
5426                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5427    }
5428
5429    private void forceStopUserLocked(int userId, String reason) {
5430        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
5431        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
5432        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5433                | Intent.FLAG_RECEIVER_FOREGROUND);
5434        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5435        broadcastIntentLocked(null, null, intent,
5436                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5437                false, false,
5438                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
5439    }
5440
5441    private final boolean killPackageProcessesLocked(String packageName, int appId,
5442            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5443            boolean doit, boolean evenPersistent, String reason) {
5444        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5445
5446        // Remove all processes this package may have touched: all with the
5447        // same UID (except for the system or root user), and all whose name
5448        // matches the package name.
5449        final int NP = mProcessNames.getMap().size();
5450        for (int ip=0; ip<NP; ip++) {
5451            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5452            final int NA = apps.size();
5453            for (int ia=0; ia<NA; ia++) {
5454                ProcessRecord app = apps.valueAt(ia);
5455                if (app.persistent && !evenPersistent) {
5456                    // we don't kill persistent processes
5457                    continue;
5458                }
5459                if (app.removed) {
5460                    if (doit) {
5461                        procs.add(app);
5462                    }
5463                    continue;
5464                }
5465
5466                // Skip process if it doesn't meet our oom adj requirement.
5467                if (app.setAdj < minOomAdj) {
5468                    continue;
5469                }
5470
5471                // If no package is specified, we call all processes under the
5472                // give user id.
5473                if (packageName == null) {
5474                    if (app.userId != userId) {
5475                        continue;
5476                    }
5477                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5478                        continue;
5479                    }
5480                // Package has been specified, we want to hit all processes
5481                // that match it.  We need to qualify this by the processes
5482                // that are running under the specified app and user ID.
5483                } else {
5484                    final boolean isDep = app.pkgDeps != null
5485                            && app.pkgDeps.contains(packageName);
5486                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5487                        continue;
5488                    }
5489                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5490                        continue;
5491                    }
5492                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5493                        continue;
5494                    }
5495                }
5496
5497                // Process has passed all conditions, kill it!
5498                if (!doit) {
5499                    return true;
5500                }
5501                app.removed = true;
5502                procs.add(app);
5503            }
5504        }
5505
5506        int N = procs.size();
5507        for (int i=0; i<N; i++) {
5508            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5509        }
5510        updateOomAdjLocked();
5511        return N > 0;
5512    }
5513
5514    private final boolean forceStopPackageLocked(String name, int appId,
5515            boolean callerWillRestart, boolean purgeCache, boolean doit,
5516            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5517        int i;
5518        int N;
5519
5520        if (userId == UserHandle.USER_ALL && name == null) {
5521            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5522        }
5523
5524        if (appId < 0 && name != null) {
5525            try {
5526                appId = UserHandle.getAppId(
5527                        AppGlobals.getPackageManager().getPackageUid(name, 0));
5528            } catch (RemoteException e) {
5529            }
5530        }
5531
5532        if (doit) {
5533            if (name != null) {
5534                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
5535                        + " user=" + userId + ": " + reason);
5536            } else {
5537                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5538            }
5539
5540            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5541            for (int ip=pmap.size()-1; ip>=0; ip--) {
5542                SparseArray<Long> ba = pmap.valueAt(ip);
5543                for (i=ba.size()-1; i>=0; i--) {
5544                    boolean remove = false;
5545                    final int entUid = ba.keyAt(i);
5546                    if (name != null) {
5547                        if (userId == UserHandle.USER_ALL) {
5548                            if (UserHandle.getAppId(entUid) == appId) {
5549                                remove = true;
5550                            }
5551                        } else {
5552                            if (entUid == UserHandle.getUid(userId, appId)) {
5553                                remove = true;
5554                            }
5555                        }
5556                    } else if (UserHandle.getUserId(entUid) == userId) {
5557                        remove = true;
5558                    }
5559                    if (remove) {
5560                        ba.removeAt(i);
5561                    }
5562                }
5563                if (ba.size() == 0) {
5564                    pmap.removeAt(ip);
5565                }
5566            }
5567        }
5568
5569        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
5570                -100, callerWillRestart, true, doit, evenPersistent,
5571                name == null ? ("stop user " + userId) : ("stop " + name));
5572
5573        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
5574            if (!doit) {
5575                return true;
5576            }
5577            didSomething = true;
5578        }
5579
5580        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
5581            if (!doit) {
5582                return true;
5583            }
5584            didSomething = true;
5585        }
5586
5587        if (name == null) {
5588            // Remove all sticky broadcasts from this user.
5589            mStickyBroadcasts.remove(userId);
5590        }
5591
5592        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
5593        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
5594                userId, providers)) {
5595            if (!doit) {
5596                return true;
5597            }
5598            didSomething = true;
5599        }
5600        N = providers.size();
5601        for (i=0; i<N; i++) {
5602            removeDyingProviderLocked(null, providers.get(i), true);
5603        }
5604
5605        // Remove transient permissions granted from/to this package/user
5606        removeUriPermissionsForPackageLocked(name, userId, false);
5607
5608        if (name == null || uninstalling) {
5609            // Remove pending intents.  For now we only do this when force
5610            // stopping users, because we have some problems when doing this
5611            // for packages -- app widgets are not currently cleaned up for
5612            // such packages, so they can be left with bad pending intents.
5613            if (mIntentSenderRecords.size() > 0) {
5614                Iterator<WeakReference<PendingIntentRecord>> it
5615                        = mIntentSenderRecords.values().iterator();
5616                while (it.hasNext()) {
5617                    WeakReference<PendingIntentRecord> wpir = it.next();
5618                    if (wpir == null) {
5619                        it.remove();
5620                        continue;
5621                    }
5622                    PendingIntentRecord pir = wpir.get();
5623                    if (pir == null) {
5624                        it.remove();
5625                        continue;
5626                    }
5627                    if (name == null) {
5628                        // Stopping user, remove all objects for the user.
5629                        if (pir.key.userId != userId) {
5630                            // Not the same user, skip it.
5631                            continue;
5632                        }
5633                    } else {
5634                        if (UserHandle.getAppId(pir.uid) != appId) {
5635                            // Different app id, skip it.
5636                            continue;
5637                        }
5638                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5639                            // Different user, skip it.
5640                            continue;
5641                        }
5642                        if (!pir.key.packageName.equals(name)) {
5643                            // Different package, skip it.
5644                            continue;
5645                        }
5646                    }
5647                    if (!doit) {
5648                        return true;
5649                    }
5650                    didSomething = true;
5651                    it.remove();
5652                    pir.canceled = true;
5653                    if (pir.key.activity != null) {
5654                        pir.key.activity.pendingResults.remove(pir.ref);
5655                    }
5656                }
5657            }
5658        }
5659
5660        if (doit) {
5661            if (purgeCache && name != null) {
5662                AttributeCache ac = AttributeCache.instance();
5663                if (ac != null) {
5664                    ac.removePackage(name);
5665                }
5666            }
5667            if (mBooted) {
5668                mStackSupervisor.resumeTopActivitiesLocked();
5669                mStackSupervisor.scheduleIdleLocked();
5670            }
5671        }
5672
5673        return didSomething;
5674    }
5675
5676    private final boolean removeProcessLocked(ProcessRecord app,
5677            boolean callerWillRestart, boolean allowRestart, String reason) {
5678        final String name = app.processName;
5679        final int uid = app.uid;
5680        if (DEBUG_PROCESSES) Slog.d(
5681            TAG, "Force removing proc " + app.toShortString() + " (" + name
5682            + "/" + uid + ")");
5683
5684        mProcessNames.remove(name, uid);
5685        mIsolatedProcesses.remove(app.uid);
5686        if (mHeavyWeightProcess == app) {
5687            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5688                    mHeavyWeightProcess.userId, 0));
5689            mHeavyWeightProcess = null;
5690        }
5691        boolean needRestart = false;
5692        if (app.pid > 0 && app.pid != MY_PID) {
5693            int pid = app.pid;
5694            synchronized (mPidsSelfLocked) {
5695                mPidsSelfLocked.remove(pid);
5696                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5697            }
5698            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5699            if (app.isolated) {
5700                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5701            }
5702            app.kill(reason, true);
5703            handleAppDiedLocked(app, true, allowRestart);
5704            removeLruProcessLocked(app);
5705
5706            if (app.persistent && !app.isolated) {
5707                if (!callerWillRestart) {
5708                    addAppLocked(app.info, false, null /* ABI override */);
5709                } else {
5710                    needRestart = true;
5711                }
5712            }
5713        } else {
5714            mRemovedProcesses.add(app);
5715        }
5716
5717        return needRestart;
5718    }
5719
5720    private final void processStartTimedOutLocked(ProcessRecord app) {
5721        final int pid = app.pid;
5722        boolean gone = false;
5723        synchronized (mPidsSelfLocked) {
5724            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5725            if (knownApp != null && knownApp.thread == null) {
5726                mPidsSelfLocked.remove(pid);
5727                gone = true;
5728            }
5729        }
5730
5731        if (gone) {
5732            Slog.w(TAG, "Process " + app + " failed to attach");
5733            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5734                    pid, app.uid, app.processName);
5735            mProcessNames.remove(app.processName, app.uid);
5736            mIsolatedProcesses.remove(app.uid);
5737            if (mHeavyWeightProcess == app) {
5738                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5739                        mHeavyWeightProcess.userId, 0));
5740                mHeavyWeightProcess = null;
5741            }
5742            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5743            if (app.isolated) {
5744                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5745            }
5746            // Take care of any launching providers waiting for this process.
5747            checkAppInLaunchingProvidersLocked(app, true);
5748            // Take care of any services that are waiting for the process.
5749            mServices.processStartTimedOutLocked(app);
5750            app.kill("start timeout", true);
5751            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5752                Slog.w(TAG, "Unattached app died before backup, skipping");
5753                try {
5754                    IBackupManager bm = IBackupManager.Stub.asInterface(
5755                            ServiceManager.getService(Context.BACKUP_SERVICE));
5756                    bm.agentDisconnected(app.info.packageName);
5757                } catch (RemoteException e) {
5758                    // Can't happen; the backup manager is local
5759                }
5760            }
5761            if (isPendingBroadcastProcessLocked(pid)) {
5762                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5763                skipPendingBroadcastLocked(pid);
5764            }
5765        } else {
5766            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5767        }
5768    }
5769
5770    private final boolean attachApplicationLocked(IApplicationThread thread,
5771            int pid) {
5772
5773        // Find the application record that is being attached...  either via
5774        // the pid if we are running in multiple processes, or just pull the
5775        // next app record if we are emulating process with anonymous threads.
5776        ProcessRecord app;
5777        if (pid != MY_PID && pid >= 0) {
5778            synchronized (mPidsSelfLocked) {
5779                app = mPidsSelfLocked.get(pid);
5780            }
5781        } else {
5782            app = null;
5783        }
5784
5785        if (app == null) {
5786            Slog.w(TAG, "No pending application record for pid " + pid
5787                    + " (IApplicationThread " + thread + "); dropping process");
5788            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5789            if (pid > 0 && pid != MY_PID) {
5790                Process.killProcessQuiet(pid);
5791                //TODO: Process.killProcessGroup(app.info.uid, pid);
5792            } else {
5793                try {
5794                    thread.scheduleExit();
5795                } catch (Exception e) {
5796                    // Ignore exceptions.
5797                }
5798            }
5799            return false;
5800        }
5801
5802        // If this application record is still attached to a previous
5803        // process, clean it up now.
5804        if (app.thread != null) {
5805            handleAppDiedLocked(app, true, true);
5806        }
5807
5808        // Tell the process all about itself.
5809
5810        if (localLOGV) Slog.v(
5811                TAG, "Binding process pid " + pid + " to record " + app);
5812
5813        final String processName = app.processName;
5814        try {
5815            AppDeathRecipient adr = new AppDeathRecipient(
5816                    app, pid, thread);
5817            thread.asBinder().linkToDeath(adr, 0);
5818            app.deathRecipient = adr;
5819        } catch (RemoteException e) {
5820            app.resetPackageList(mProcessStats);
5821            startProcessLocked(app, "link fail", processName);
5822            return false;
5823        }
5824
5825        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5826
5827        app.makeActive(thread, mProcessStats);
5828        app.curAdj = app.setAdj = -100;
5829        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5830        app.forcingToForeground = null;
5831        updateProcessForegroundLocked(app, false, false);
5832        app.hasShownUi = false;
5833        app.debugging = false;
5834        app.cached = false;
5835
5836        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5837
5838        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5839        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5840
5841        if (!normalMode) {
5842            Slog.i(TAG, "Launching preboot mode app: " + app);
5843        }
5844
5845        if (localLOGV) Slog.v(
5846            TAG, "New app record " + app
5847            + " thread=" + thread.asBinder() + " pid=" + pid);
5848        try {
5849            int testMode = IApplicationThread.DEBUG_OFF;
5850            if (mDebugApp != null && mDebugApp.equals(processName)) {
5851                testMode = mWaitForDebugger
5852                    ? IApplicationThread.DEBUG_WAIT
5853                    : IApplicationThread.DEBUG_ON;
5854                app.debugging = true;
5855                if (mDebugTransient) {
5856                    mDebugApp = mOrigDebugApp;
5857                    mWaitForDebugger = mOrigWaitForDebugger;
5858                }
5859            }
5860            String profileFile = app.instrumentationProfileFile;
5861            ParcelFileDescriptor profileFd = null;
5862            int samplingInterval = 0;
5863            boolean profileAutoStop = false;
5864            if (mProfileApp != null && mProfileApp.equals(processName)) {
5865                mProfileProc = app;
5866                profileFile = mProfileFile;
5867                profileFd = mProfileFd;
5868                samplingInterval = mSamplingInterval;
5869                profileAutoStop = mAutoStopProfiler;
5870            }
5871            boolean enableOpenGlTrace = false;
5872            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
5873                enableOpenGlTrace = true;
5874                mOpenGlTraceApp = null;
5875            }
5876
5877            // If the app is being launched for restore or full backup, set it up specially
5878            boolean isRestrictedBackupMode = false;
5879            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
5880                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
5881                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
5882                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
5883            }
5884
5885            ensurePackageDexOpt(app.instrumentationInfo != null
5886                    ? app.instrumentationInfo.packageName
5887                    : app.info.packageName);
5888            if (app.instrumentationClass != null) {
5889                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
5890            }
5891            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
5892                    + processName + " with config " + mConfiguration);
5893            ApplicationInfo appInfo = app.instrumentationInfo != null
5894                    ? app.instrumentationInfo : app.info;
5895            app.compat = compatibilityInfoForPackageLocked(appInfo);
5896            if (profileFd != null) {
5897                profileFd = profileFd.dup();
5898            }
5899            ProfilerInfo profilerInfo = profileFile == null ? null
5900                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
5901            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
5902                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
5903                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
5904                    isRestrictedBackupMode || !normalMode, app.persistent,
5905                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
5906                    mCoreSettingsObserver.getCoreSettingsLocked());
5907            updateLruProcessLocked(app, false, null);
5908            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
5909        } catch (Exception e) {
5910            // todo: Yikes!  What should we do?  For now we will try to
5911            // start another process, but that could easily get us in
5912            // an infinite loop of restarting processes...
5913            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
5914
5915            app.resetPackageList(mProcessStats);
5916            app.unlinkDeathRecipient();
5917            startProcessLocked(app, "bind fail", processName);
5918            return false;
5919        }
5920
5921        // Remove this record from the list of starting applications.
5922        mPersistentStartingProcesses.remove(app);
5923        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
5924                "Attach application locked removing on hold: " + app);
5925        mProcessesOnHold.remove(app);
5926
5927        boolean badApp = false;
5928        boolean didSomething = false;
5929
5930        // See if the top visible activity is waiting to run in this process...
5931        if (normalMode) {
5932            try {
5933                if (mStackSupervisor.attachApplicationLocked(app)) {
5934                    didSomething = true;
5935                }
5936            } catch (Exception e) {
5937                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
5938                badApp = true;
5939            }
5940        }
5941
5942        // Find any services that should be running in this process...
5943        if (!badApp) {
5944            try {
5945                didSomething |= mServices.attachApplicationLocked(app, processName);
5946            } catch (Exception e) {
5947                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
5948                badApp = true;
5949            }
5950        }
5951
5952        // Check if a next-broadcast receiver is in this process...
5953        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
5954            try {
5955                didSomething |= sendPendingBroadcastsLocked(app);
5956            } catch (Exception e) {
5957                // If the app died trying to launch the receiver we declare it 'bad'
5958                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
5959                badApp = true;
5960            }
5961        }
5962
5963        // Check whether the next backup agent is in this process...
5964        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
5965            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
5966            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
5967            try {
5968                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
5969                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
5970                        mBackupTarget.backupMode);
5971            } catch (Exception e) {
5972                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
5973                badApp = true;
5974            }
5975        }
5976
5977        if (badApp) {
5978            app.kill("error during init", true);
5979            handleAppDiedLocked(app, false, true);
5980            return false;
5981        }
5982
5983        if (!didSomething) {
5984            updateOomAdjLocked();
5985        }
5986
5987        return true;
5988    }
5989
5990    @Override
5991    public final void attachApplication(IApplicationThread thread) {
5992        synchronized (this) {
5993            int callingPid = Binder.getCallingPid();
5994            final long origId = Binder.clearCallingIdentity();
5995            attachApplicationLocked(thread, callingPid);
5996            Binder.restoreCallingIdentity(origId);
5997        }
5998    }
5999
6000    @Override
6001    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6002        final long origId = Binder.clearCallingIdentity();
6003        synchronized (this) {
6004            ActivityStack stack = ActivityRecord.getStackLocked(token);
6005            if (stack != null) {
6006                ActivityRecord r =
6007                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6008                if (stopProfiling) {
6009                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6010                        try {
6011                            mProfileFd.close();
6012                        } catch (IOException e) {
6013                        }
6014                        clearProfilerLocked();
6015                    }
6016                }
6017            }
6018        }
6019        Binder.restoreCallingIdentity(origId);
6020    }
6021
6022    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6023        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6024                finishBooting? 1 : 0, enableScreen ? 1 : 0));
6025    }
6026
6027    void enableScreenAfterBoot() {
6028        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6029                SystemClock.uptimeMillis());
6030        mWindowManager.enableScreenAfterBoot();
6031
6032        synchronized (this) {
6033            updateEventDispatchingLocked();
6034        }
6035    }
6036
6037    @Override
6038    public void showBootMessage(final CharSequence msg, final boolean always) {
6039        enforceNotIsolatedCaller("showBootMessage");
6040        mWindowManager.showBootMessage(msg, always);
6041    }
6042
6043    @Override
6044    public void keyguardWaitingForActivityDrawn() {
6045        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6046        final long token = Binder.clearCallingIdentity();
6047        try {
6048            synchronized (this) {
6049                if (DEBUG_LOCKSCREEN) logLockScreen("");
6050                mWindowManager.keyguardWaitingForActivityDrawn();
6051                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6052                    mLockScreenShown = LOCK_SCREEN_LEAVING;
6053                }
6054            }
6055        } finally {
6056            Binder.restoreCallingIdentity(token);
6057        }
6058    }
6059
6060    final void finishBooting() {
6061        synchronized (this) {
6062            if (!mBootAnimationComplete) {
6063                mCallFinishBooting = true;
6064                return;
6065            }
6066            mCallFinishBooting = false;
6067        }
6068
6069        ArraySet<String> completedIsas = new ArraySet<String>();
6070        for (String abi : Build.SUPPORTED_ABIS) {
6071            Process.establishZygoteConnectionForAbi(abi);
6072            final String instructionSet = VMRuntime.getInstructionSet(abi);
6073            if (!completedIsas.contains(instructionSet)) {
6074                if (mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi)) != 0) {
6075                    Slog.e(TAG, "Unable to mark boot complete for abi: " + abi);
6076                }
6077                completedIsas.add(instructionSet);
6078            }
6079        }
6080
6081        IntentFilter pkgFilter = new IntentFilter();
6082        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6083        pkgFilter.addDataScheme("package");
6084        mContext.registerReceiver(new BroadcastReceiver() {
6085            @Override
6086            public void onReceive(Context context, Intent intent) {
6087                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6088                if (pkgs != null) {
6089                    for (String pkg : pkgs) {
6090                        synchronized (ActivityManagerService.this) {
6091                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6092                                    0, "finished booting")) {
6093                                setResultCode(Activity.RESULT_OK);
6094                                return;
6095                            }
6096                        }
6097                    }
6098                }
6099            }
6100        }, pkgFilter);
6101
6102        // Let system services know.
6103        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6104
6105        synchronized (this) {
6106            // Ensure that any processes we had put on hold are now started
6107            // up.
6108            final int NP = mProcessesOnHold.size();
6109            if (NP > 0) {
6110                ArrayList<ProcessRecord> procs =
6111                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6112                for (int ip=0; ip<NP; ip++) {
6113                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
6114                            + procs.get(ip));
6115                    startProcessLocked(procs.get(ip), "on-hold", null);
6116                }
6117            }
6118
6119            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6120                // Start looking for apps that are abusing wake locks.
6121                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6122                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6123                // Tell anyone interested that we are done booting!
6124                SystemProperties.set("sys.boot_completed", "1");
6125
6126                // And trigger dev.bootcomplete if we are not showing encryption progress
6127                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6128                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6129                    SystemProperties.set("dev.bootcomplete", "1");
6130                }
6131                for (int i=0; i<mStartedUsers.size(); i++) {
6132                    UserStartedState uss = mStartedUsers.valueAt(i);
6133                    if (uss.mState == UserStartedState.STATE_BOOTING) {
6134                        uss.mState = UserStartedState.STATE_RUNNING;
6135                        final int userId = mStartedUsers.keyAt(i);
6136                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
6137                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
6138                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
6139                        broadcastIntentLocked(null, null, intent, null,
6140                                new IIntentReceiver.Stub() {
6141                                    @Override
6142                                    public void performReceive(Intent intent, int resultCode,
6143                                            String data, Bundle extras, boolean ordered,
6144                                            boolean sticky, int sendingUser) {
6145                                        synchronized (ActivityManagerService.this) {
6146                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6147                                                    true, false);
6148                                        }
6149                                    }
6150                                },
6151                                0, null, null,
6152                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
6153                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
6154                                userId);
6155                    }
6156                }
6157                scheduleStartProfilesLocked();
6158            }
6159        }
6160    }
6161
6162    @Override
6163    public void bootAnimationComplete() {
6164        final boolean callFinishBooting;
6165        synchronized (this) {
6166            callFinishBooting = mCallFinishBooting;
6167            mBootAnimationComplete = true;
6168        }
6169        if (callFinishBooting) {
6170            finishBooting();
6171        }
6172    }
6173
6174    final void ensureBootCompleted() {
6175        boolean booting;
6176        boolean enableScreen;
6177        synchronized (this) {
6178            booting = mBooting;
6179            mBooting = false;
6180            enableScreen = !mBooted;
6181            mBooted = true;
6182        }
6183
6184        if (booting) {
6185            finishBooting();
6186        }
6187
6188        if (enableScreen) {
6189            enableScreenAfterBoot();
6190        }
6191    }
6192
6193    @Override
6194    public final void activityResumed(IBinder token) {
6195        final long origId = Binder.clearCallingIdentity();
6196        synchronized(this) {
6197            ActivityStack stack = ActivityRecord.getStackLocked(token);
6198            if (stack != null) {
6199                ActivityRecord.activityResumedLocked(token);
6200            }
6201        }
6202        Binder.restoreCallingIdentity(origId);
6203    }
6204
6205    @Override
6206    public final void activityPaused(IBinder token) {
6207        final long origId = Binder.clearCallingIdentity();
6208        synchronized(this) {
6209            ActivityStack stack = ActivityRecord.getStackLocked(token);
6210            if (stack != null) {
6211                stack.activityPausedLocked(token, false);
6212            }
6213        }
6214        Binder.restoreCallingIdentity(origId);
6215    }
6216
6217    @Override
6218    public final void activityStopped(IBinder token, Bundle icicle,
6219            PersistableBundle persistentState, CharSequence description) {
6220        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
6221
6222        // Refuse possible leaked file descriptors
6223        if (icicle != null && icicle.hasFileDescriptors()) {
6224            throw new IllegalArgumentException("File descriptors passed in Bundle");
6225        }
6226
6227        final long origId = Binder.clearCallingIdentity();
6228
6229        synchronized (this) {
6230            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6231            if (r != null) {
6232                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6233            }
6234        }
6235
6236        trimApplications();
6237
6238        Binder.restoreCallingIdentity(origId);
6239    }
6240
6241    @Override
6242    public final void activityDestroyed(IBinder token) {
6243        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
6244        synchronized (this) {
6245            ActivityStack stack = ActivityRecord.getStackLocked(token);
6246            if (stack != null) {
6247                stack.activityDestroyedLocked(token);
6248            }
6249        }
6250    }
6251
6252    @Override
6253    public final void backgroundResourcesReleased(IBinder token) {
6254        final long origId = Binder.clearCallingIdentity();
6255        try {
6256            synchronized (this) {
6257                ActivityStack stack = ActivityRecord.getStackLocked(token);
6258                if (stack != null) {
6259                    stack.backgroundResourcesReleased(token);
6260                }
6261            }
6262        } finally {
6263            Binder.restoreCallingIdentity(origId);
6264        }
6265    }
6266
6267    @Override
6268    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6269        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6270    }
6271
6272    @Override
6273    public final void notifyEnterAnimationComplete(IBinder token) {
6274        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6275    }
6276
6277    @Override
6278    public String getCallingPackage(IBinder token) {
6279        synchronized (this) {
6280            ActivityRecord r = getCallingRecordLocked(token);
6281            return r != null ? r.info.packageName : null;
6282        }
6283    }
6284
6285    @Override
6286    public ComponentName getCallingActivity(IBinder token) {
6287        synchronized (this) {
6288            ActivityRecord r = getCallingRecordLocked(token);
6289            return r != null ? r.intent.getComponent() : null;
6290        }
6291    }
6292
6293    private ActivityRecord getCallingRecordLocked(IBinder token) {
6294        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6295        if (r == null) {
6296            return null;
6297        }
6298        return r.resultTo;
6299    }
6300
6301    @Override
6302    public ComponentName getActivityClassForToken(IBinder token) {
6303        synchronized(this) {
6304            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6305            if (r == null) {
6306                return null;
6307            }
6308            return r.intent.getComponent();
6309        }
6310    }
6311
6312    @Override
6313    public String getPackageForToken(IBinder token) {
6314        synchronized(this) {
6315            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6316            if (r == null) {
6317                return null;
6318            }
6319            return r.packageName;
6320        }
6321    }
6322
6323    @Override
6324    public IIntentSender getIntentSender(int type,
6325            String packageName, IBinder token, String resultWho,
6326            int requestCode, Intent[] intents, String[] resolvedTypes,
6327            int flags, Bundle options, int userId) {
6328        enforceNotIsolatedCaller("getIntentSender");
6329        // Refuse possible leaked file descriptors
6330        if (intents != null) {
6331            if (intents.length < 1) {
6332                throw new IllegalArgumentException("Intents array length must be >= 1");
6333            }
6334            for (int i=0; i<intents.length; i++) {
6335                Intent intent = intents[i];
6336                if (intent != null) {
6337                    if (intent.hasFileDescriptors()) {
6338                        throw new IllegalArgumentException("File descriptors passed in Intent");
6339                    }
6340                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6341                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6342                        throw new IllegalArgumentException(
6343                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6344                    }
6345                    intents[i] = new Intent(intent);
6346                }
6347            }
6348            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6349                throw new IllegalArgumentException(
6350                        "Intent array length does not match resolvedTypes length");
6351            }
6352        }
6353        if (options != null) {
6354            if (options.hasFileDescriptors()) {
6355                throw new IllegalArgumentException("File descriptors passed in options");
6356            }
6357        }
6358
6359        synchronized(this) {
6360            int callingUid = Binder.getCallingUid();
6361            int origUserId = userId;
6362            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6363                    type == ActivityManager.INTENT_SENDER_BROADCAST,
6364                    ALLOW_NON_FULL, "getIntentSender", null);
6365            if (origUserId == UserHandle.USER_CURRENT) {
6366                // We don't want to evaluate this until the pending intent is
6367                // actually executed.  However, we do want to always do the
6368                // security checking for it above.
6369                userId = UserHandle.USER_CURRENT;
6370            }
6371            try {
6372                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6373                    int uid = AppGlobals.getPackageManager()
6374                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
6375                    if (!UserHandle.isSameApp(callingUid, uid)) {
6376                        String msg = "Permission Denial: getIntentSender() from pid="
6377                            + Binder.getCallingPid()
6378                            + ", uid=" + Binder.getCallingUid()
6379                            + ", (need uid=" + uid + ")"
6380                            + " is not allowed to send as package " + packageName;
6381                        Slog.w(TAG, msg);
6382                        throw new SecurityException(msg);
6383                    }
6384                }
6385
6386                return getIntentSenderLocked(type, packageName, callingUid, userId,
6387                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
6388
6389            } catch (RemoteException e) {
6390                throw new SecurityException(e);
6391            }
6392        }
6393    }
6394
6395    IIntentSender getIntentSenderLocked(int type, String packageName,
6396            int callingUid, int userId, IBinder token, String resultWho,
6397            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6398            Bundle options) {
6399        if (DEBUG_MU)
6400            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6401        ActivityRecord activity = null;
6402        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6403            activity = ActivityRecord.isInStackLocked(token);
6404            if (activity == null) {
6405                return null;
6406            }
6407            if (activity.finishing) {
6408                return null;
6409            }
6410        }
6411
6412        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6413        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6414        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6415        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6416                |PendingIntent.FLAG_UPDATE_CURRENT);
6417
6418        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6419                type, packageName, activity, resultWho,
6420                requestCode, intents, resolvedTypes, flags, options, userId);
6421        WeakReference<PendingIntentRecord> ref;
6422        ref = mIntentSenderRecords.get(key);
6423        PendingIntentRecord rec = ref != null ? ref.get() : null;
6424        if (rec != null) {
6425            if (!cancelCurrent) {
6426                if (updateCurrent) {
6427                    if (rec.key.requestIntent != null) {
6428                        rec.key.requestIntent.replaceExtras(intents != null ?
6429                                intents[intents.length - 1] : null);
6430                    }
6431                    if (intents != null) {
6432                        intents[intents.length-1] = rec.key.requestIntent;
6433                        rec.key.allIntents = intents;
6434                        rec.key.allResolvedTypes = resolvedTypes;
6435                    } else {
6436                        rec.key.allIntents = null;
6437                        rec.key.allResolvedTypes = null;
6438                    }
6439                }
6440                return rec;
6441            }
6442            rec.canceled = true;
6443            mIntentSenderRecords.remove(key);
6444        }
6445        if (noCreate) {
6446            return rec;
6447        }
6448        rec = new PendingIntentRecord(this, key, callingUid);
6449        mIntentSenderRecords.put(key, rec.ref);
6450        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6451            if (activity.pendingResults == null) {
6452                activity.pendingResults
6453                        = new HashSet<WeakReference<PendingIntentRecord>>();
6454            }
6455            activity.pendingResults.add(rec.ref);
6456        }
6457        return rec;
6458    }
6459
6460    @Override
6461    public void cancelIntentSender(IIntentSender sender) {
6462        if (!(sender instanceof PendingIntentRecord)) {
6463            return;
6464        }
6465        synchronized(this) {
6466            PendingIntentRecord rec = (PendingIntentRecord)sender;
6467            try {
6468                int uid = AppGlobals.getPackageManager()
6469                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
6470                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6471                    String msg = "Permission Denial: cancelIntentSender() from pid="
6472                        + Binder.getCallingPid()
6473                        + ", uid=" + Binder.getCallingUid()
6474                        + " is not allowed to cancel packges "
6475                        + rec.key.packageName;
6476                    Slog.w(TAG, msg);
6477                    throw new SecurityException(msg);
6478                }
6479            } catch (RemoteException e) {
6480                throw new SecurityException(e);
6481            }
6482            cancelIntentSenderLocked(rec, true);
6483        }
6484    }
6485
6486    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
6487        rec.canceled = true;
6488        mIntentSenderRecords.remove(rec.key);
6489        if (cleanActivity && rec.key.activity != null) {
6490            rec.key.activity.pendingResults.remove(rec.ref);
6491        }
6492    }
6493
6494    @Override
6495    public String getPackageForIntentSender(IIntentSender pendingResult) {
6496        if (!(pendingResult instanceof PendingIntentRecord)) {
6497            return null;
6498        }
6499        try {
6500            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6501            return res.key.packageName;
6502        } catch (ClassCastException e) {
6503        }
6504        return null;
6505    }
6506
6507    @Override
6508    public int getUidForIntentSender(IIntentSender sender) {
6509        if (sender instanceof PendingIntentRecord) {
6510            try {
6511                PendingIntentRecord res = (PendingIntentRecord)sender;
6512                return res.uid;
6513            } catch (ClassCastException e) {
6514            }
6515        }
6516        return -1;
6517    }
6518
6519    @Override
6520    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
6521        if (!(pendingResult instanceof PendingIntentRecord)) {
6522            return false;
6523        }
6524        try {
6525            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6526            if (res.key.allIntents == null) {
6527                return false;
6528            }
6529            for (int i=0; i<res.key.allIntents.length; i++) {
6530                Intent intent = res.key.allIntents[i];
6531                if (intent.getPackage() != null && intent.getComponent() != null) {
6532                    return false;
6533                }
6534            }
6535            return true;
6536        } catch (ClassCastException e) {
6537        }
6538        return false;
6539    }
6540
6541    @Override
6542    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
6543        if (!(pendingResult instanceof PendingIntentRecord)) {
6544            return false;
6545        }
6546        try {
6547            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6548            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6549                return true;
6550            }
6551            return false;
6552        } catch (ClassCastException e) {
6553        }
6554        return false;
6555    }
6556
6557    @Override
6558    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6559        if (!(pendingResult instanceof PendingIntentRecord)) {
6560            return null;
6561        }
6562        try {
6563            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6564            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6565        } catch (ClassCastException e) {
6566        }
6567        return null;
6568    }
6569
6570    @Override
6571    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6572        if (!(pendingResult instanceof PendingIntentRecord)) {
6573            return null;
6574        }
6575        try {
6576            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6577            Intent intent = res.key.requestIntent;
6578            if (intent != null) {
6579                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6580                        || res.lastTagPrefix.equals(prefix))) {
6581                    return res.lastTag;
6582                }
6583                res.lastTagPrefix = prefix;
6584                StringBuilder sb = new StringBuilder(128);
6585                if (prefix != null) {
6586                    sb.append(prefix);
6587                }
6588                if (intent.getAction() != null) {
6589                    sb.append(intent.getAction());
6590                } else if (intent.getComponent() != null) {
6591                    intent.getComponent().appendShortString(sb);
6592                } else {
6593                    sb.append("?");
6594                }
6595                return res.lastTag = sb.toString();
6596            }
6597        } catch (ClassCastException e) {
6598        }
6599        return null;
6600    }
6601
6602    @Override
6603    public void setProcessLimit(int max) {
6604        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6605                "setProcessLimit()");
6606        synchronized (this) {
6607            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6608            mProcessLimitOverride = max;
6609        }
6610        trimApplications();
6611    }
6612
6613    @Override
6614    public int getProcessLimit() {
6615        synchronized (this) {
6616            return mProcessLimitOverride;
6617        }
6618    }
6619
6620    void foregroundTokenDied(ForegroundToken token) {
6621        synchronized (ActivityManagerService.this) {
6622            synchronized (mPidsSelfLocked) {
6623                ForegroundToken cur
6624                    = mForegroundProcesses.get(token.pid);
6625                if (cur != token) {
6626                    return;
6627                }
6628                mForegroundProcesses.remove(token.pid);
6629                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6630                if (pr == null) {
6631                    return;
6632                }
6633                pr.forcingToForeground = null;
6634                updateProcessForegroundLocked(pr, false, false);
6635            }
6636            updateOomAdjLocked();
6637        }
6638    }
6639
6640    @Override
6641    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6642        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6643                "setProcessForeground()");
6644        synchronized(this) {
6645            boolean changed = false;
6646
6647            synchronized (mPidsSelfLocked) {
6648                ProcessRecord pr = mPidsSelfLocked.get(pid);
6649                if (pr == null && isForeground) {
6650                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6651                    return;
6652                }
6653                ForegroundToken oldToken = mForegroundProcesses.get(pid);
6654                if (oldToken != null) {
6655                    oldToken.token.unlinkToDeath(oldToken, 0);
6656                    mForegroundProcesses.remove(pid);
6657                    if (pr != null) {
6658                        pr.forcingToForeground = null;
6659                    }
6660                    changed = true;
6661                }
6662                if (isForeground && token != null) {
6663                    ForegroundToken newToken = new ForegroundToken() {
6664                        @Override
6665                        public void binderDied() {
6666                            foregroundTokenDied(this);
6667                        }
6668                    };
6669                    newToken.pid = pid;
6670                    newToken.token = token;
6671                    try {
6672                        token.linkToDeath(newToken, 0);
6673                        mForegroundProcesses.put(pid, newToken);
6674                        pr.forcingToForeground = token;
6675                        changed = true;
6676                    } catch (RemoteException e) {
6677                        // If the process died while doing this, we will later
6678                        // do the cleanup with the process death link.
6679                    }
6680                }
6681            }
6682
6683            if (changed) {
6684                updateOomAdjLocked();
6685            }
6686        }
6687    }
6688
6689    // =========================================================
6690    // PERMISSIONS
6691    // =========================================================
6692
6693    static class PermissionController extends IPermissionController.Stub {
6694        ActivityManagerService mActivityManagerService;
6695        PermissionController(ActivityManagerService activityManagerService) {
6696            mActivityManagerService = activityManagerService;
6697        }
6698
6699        @Override
6700        public boolean checkPermission(String permission, int pid, int uid) {
6701            return mActivityManagerService.checkPermission(permission, pid,
6702                    uid) == PackageManager.PERMISSION_GRANTED;
6703        }
6704    }
6705
6706    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6707        @Override
6708        public int checkComponentPermission(String permission, int pid, int uid,
6709                int owningUid, boolean exported) {
6710            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6711                    owningUid, exported);
6712        }
6713
6714        @Override
6715        public Object getAMSLock() {
6716            return ActivityManagerService.this;
6717        }
6718    }
6719
6720    /**
6721     * This can be called with or without the global lock held.
6722     */
6723    int checkComponentPermission(String permission, int pid, int uid,
6724            int owningUid, boolean exported) {
6725        // We might be performing an operation on behalf of an indirect binder
6726        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
6727        // client identity accordingly before proceeding.
6728        Identity tlsIdentity = sCallerIdentity.get();
6729        if (tlsIdentity != null) {
6730            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6731                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6732            uid = tlsIdentity.uid;
6733            pid = tlsIdentity.pid;
6734        }
6735
6736        if (pid == MY_PID) {
6737            return PackageManager.PERMISSION_GRANTED;
6738        }
6739
6740        return ActivityManager.checkComponentPermission(permission, uid,
6741                owningUid, exported);
6742    }
6743
6744    /**
6745     * As the only public entry point for permissions checking, this method
6746     * can enforce the semantic that requesting a check on a null global
6747     * permission is automatically denied.  (Internally a null permission
6748     * string is used when calling {@link #checkComponentPermission} in cases
6749     * when only uid-based security is needed.)
6750     *
6751     * This can be called with or without the global lock held.
6752     */
6753    @Override
6754    public int checkPermission(String permission, int pid, int uid) {
6755        if (permission == null) {
6756            return PackageManager.PERMISSION_DENIED;
6757        }
6758        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6759    }
6760
6761    /**
6762     * Binder IPC calls go through the public entry point.
6763     * This can be called with or without the global lock held.
6764     */
6765    int checkCallingPermission(String permission) {
6766        return checkPermission(permission,
6767                Binder.getCallingPid(),
6768                UserHandle.getAppId(Binder.getCallingUid()));
6769    }
6770
6771    /**
6772     * This can be called with or without the global lock held.
6773     */
6774    void enforceCallingPermission(String permission, String func) {
6775        if (checkCallingPermission(permission)
6776                == PackageManager.PERMISSION_GRANTED) {
6777            return;
6778        }
6779
6780        String msg = "Permission Denial: " + func + " from pid="
6781                + Binder.getCallingPid()
6782                + ", uid=" + Binder.getCallingUid()
6783                + " requires " + permission;
6784        Slog.w(TAG, msg);
6785        throw new SecurityException(msg);
6786    }
6787
6788    /**
6789     * Determine if UID is holding permissions required to access {@link Uri} in
6790     * the given {@link ProviderInfo}. Final permission checking is always done
6791     * in {@link ContentProvider}.
6792     */
6793    private final boolean checkHoldingPermissionsLocked(
6794            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
6795        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6796                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
6797        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
6798            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
6799                    != PERMISSION_GRANTED) {
6800                return false;
6801            }
6802        }
6803        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
6804    }
6805
6806    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
6807            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
6808        if (pi.applicationInfo.uid == uid) {
6809            return true;
6810        } else if (!pi.exported) {
6811            return false;
6812        }
6813
6814        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6815        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6816        try {
6817            // check if target holds top-level <provider> permissions
6818            if (!readMet && pi.readPermission != null && considerUidPermissions
6819                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6820                readMet = true;
6821            }
6822            if (!writeMet && pi.writePermission != null && considerUidPermissions
6823                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6824                writeMet = true;
6825            }
6826
6827            // track if unprotected read/write is allowed; any denied
6828            // <path-permission> below removes this ability
6829            boolean allowDefaultRead = pi.readPermission == null;
6830            boolean allowDefaultWrite = pi.writePermission == null;
6831
6832            // check if target holds any <path-permission> that match uri
6833            final PathPermission[] pps = pi.pathPermissions;
6834            if (pps != null) {
6835                final String path = grantUri.uri.getPath();
6836                int i = pps.length;
6837                while (i > 0 && (!readMet || !writeMet)) {
6838                    i--;
6839                    PathPermission pp = pps[i];
6840                    if (pp.match(path)) {
6841                        if (!readMet) {
6842                            final String pprperm = pp.getReadPermission();
6843                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
6844                                    + pprperm + " for " + pp.getPath()
6845                                    + ": match=" + pp.match(path)
6846                                    + " check=" + pm.checkUidPermission(pprperm, uid));
6847                            if (pprperm != null) {
6848                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
6849                                        == PERMISSION_GRANTED) {
6850                                    readMet = true;
6851                                } else {
6852                                    allowDefaultRead = false;
6853                                }
6854                            }
6855                        }
6856                        if (!writeMet) {
6857                            final String ppwperm = pp.getWritePermission();
6858                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
6859                                    + ppwperm + " for " + pp.getPath()
6860                                    + ": match=" + pp.match(path)
6861                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
6862                            if (ppwperm != null) {
6863                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
6864                                        == PERMISSION_GRANTED) {
6865                                    writeMet = true;
6866                                } else {
6867                                    allowDefaultWrite = false;
6868                                }
6869                            }
6870                        }
6871                    }
6872                }
6873            }
6874
6875            // grant unprotected <provider> read/write, if not blocked by
6876            // <path-permission> above
6877            if (allowDefaultRead) readMet = true;
6878            if (allowDefaultWrite) writeMet = true;
6879
6880        } catch (RemoteException e) {
6881            return false;
6882        }
6883
6884        return readMet && writeMet;
6885    }
6886
6887    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
6888        ProviderInfo pi = null;
6889        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
6890        if (cpr != null) {
6891            pi = cpr.info;
6892        } else {
6893            try {
6894                pi = AppGlobals.getPackageManager().resolveContentProvider(
6895                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
6896            } catch (RemoteException ex) {
6897            }
6898        }
6899        return pi;
6900    }
6901
6902    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
6903        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6904        if (targetUris != null) {
6905            return targetUris.get(grantUri);
6906        }
6907        return null;
6908    }
6909
6910    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
6911            String targetPkg, int targetUid, GrantUri grantUri) {
6912        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6913        if (targetUris == null) {
6914            targetUris = Maps.newArrayMap();
6915            mGrantedUriPermissions.put(targetUid, targetUris);
6916        }
6917
6918        UriPermission perm = targetUris.get(grantUri);
6919        if (perm == null) {
6920            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
6921            targetUris.put(grantUri, perm);
6922        }
6923
6924        return perm;
6925    }
6926
6927    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
6928            final int modeFlags) {
6929        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
6930        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
6931                : UriPermission.STRENGTH_OWNED;
6932
6933        // Root gets to do everything.
6934        if (uid == 0) {
6935            return true;
6936        }
6937
6938        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6939        if (perms == null) return false;
6940
6941        // First look for exact match
6942        final UriPermission exactPerm = perms.get(grantUri);
6943        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
6944            return true;
6945        }
6946
6947        // No exact match, look for prefixes
6948        final int N = perms.size();
6949        for (int i = 0; i < N; i++) {
6950            final UriPermission perm = perms.valueAt(i);
6951            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
6952                    && perm.getStrength(modeFlags) >= minStrength) {
6953                return true;
6954            }
6955        }
6956
6957        return false;
6958    }
6959
6960    /**
6961     * @param uri This uri must NOT contain an embedded userId.
6962     * @param userId The userId in which the uri is to be resolved.
6963     */
6964    @Override
6965    public int checkUriPermission(Uri uri, int pid, int uid,
6966            final int modeFlags, int userId) {
6967        enforceNotIsolatedCaller("checkUriPermission");
6968
6969        // Another redirected-binder-call permissions check as in
6970        // {@link checkComponentPermission}.
6971        Identity tlsIdentity = sCallerIdentity.get();
6972        if (tlsIdentity != null) {
6973            uid = tlsIdentity.uid;
6974            pid = tlsIdentity.pid;
6975        }
6976
6977        // Our own process gets to do everything.
6978        if (pid == MY_PID) {
6979            return PackageManager.PERMISSION_GRANTED;
6980        }
6981        synchronized (this) {
6982            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
6983                    ? PackageManager.PERMISSION_GRANTED
6984                    : PackageManager.PERMISSION_DENIED;
6985        }
6986    }
6987
6988    /**
6989     * Check if the targetPkg can be granted permission to access uri by
6990     * the callingUid using the given modeFlags.  Throws a security exception
6991     * if callingUid is not allowed to do this.  Returns the uid of the target
6992     * if the URI permission grant should be performed; returns -1 if it is not
6993     * needed (for example targetPkg already has permission to access the URI).
6994     * If you already know the uid of the target, you can supply it in
6995     * lastTargetUid else set that to -1.
6996     */
6997    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6998            final int modeFlags, int lastTargetUid) {
6999        if (!Intent.isAccessUriMode(modeFlags)) {
7000            return -1;
7001        }
7002
7003        if (targetPkg != null) {
7004            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7005                    "Checking grant " + targetPkg + " permission to " + grantUri);
7006        }
7007
7008        final IPackageManager pm = AppGlobals.getPackageManager();
7009
7010        // If this is not a content: uri, we can't do anything with it.
7011        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7012            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7013                    "Can't grant URI permission for non-content URI: " + grantUri);
7014            return -1;
7015        }
7016
7017        final String authority = grantUri.uri.getAuthority();
7018        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7019        if (pi == null) {
7020            Slog.w(TAG, "No content provider found for permission check: " +
7021                    grantUri.uri.toSafeString());
7022            return -1;
7023        }
7024
7025        int targetUid = lastTargetUid;
7026        if (targetUid < 0 && targetPkg != null) {
7027            try {
7028                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
7029                if (targetUid < 0) {
7030                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7031                            "Can't grant URI permission no uid for: " + targetPkg);
7032                    return -1;
7033                }
7034            } catch (RemoteException ex) {
7035                return -1;
7036            }
7037        }
7038
7039        if (targetUid >= 0) {
7040            // First...  does the target actually need this permission?
7041            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7042                // No need to grant the target this permission.
7043                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7044                        "Target " + targetPkg + " already has full permission to " + grantUri);
7045                return -1;
7046            }
7047        } else {
7048            // First...  there is no target package, so can anyone access it?
7049            boolean allowed = pi.exported;
7050            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7051                if (pi.readPermission != null) {
7052                    allowed = false;
7053                }
7054            }
7055            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7056                if (pi.writePermission != null) {
7057                    allowed = false;
7058                }
7059            }
7060            if (allowed) {
7061                return -1;
7062            }
7063        }
7064
7065        /* There is a special cross user grant if:
7066         * - The target is on another user.
7067         * - Apps on the current user can access the uri without any uid permissions.
7068         * In this case, we grant a uri permission, even if the ContentProvider does not normally
7069         * grant uri permissions.
7070         */
7071        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7072                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7073                modeFlags, false /*without considering the uid permissions*/);
7074
7075        // Second...  is the provider allowing granting of URI permissions?
7076        if (!specialCrossUserGrant) {
7077            if (!pi.grantUriPermissions) {
7078                throw new SecurityException("Provider " + pi.packageName
7079                        + "/" + pi.name
7080                        + " does not allow granting of Uri permissions (uri "
7081                        + grantUri + ")");
7082            }
7083            if (pi.uriPermissionPatterns != null) {
7084                final int N = pi.uriPermissionPatterns.length;
7085                boolean allowed = false;
7086                for (int i=0; i<N; i++) {
7087                    if (pi.uriPermissionPatterns[i] != null
7088                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7089                        allowed = true;
7090                        break;
7091                    }
7092                }
7093                if (!allowed) {
7094                    throw new SecurityException("Provider " + pi.packageName
7095                            + "/" + pi.name
7096                            + " does not allow granting of permission to path of Uri "
7097                            + grantUri);
7098                }
7099            }
7100        }
7101
7102        // Third...  does the caller itself have permission to access
7103        // this uri?
7104        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
7105            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7106                // Require they hold a strong enough Uri permission
7107                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7108                    throw new SecurityException("Uid " + callingUid
7109                            + " does not have permission to uri " + grantUri);
7110                }
7111            }
7112        }
7113        return targetUid;
7114    }
7115
7116    /**
7117     * @param uri This uri must NOT contain an embedded userId.
7118     * @param userId The userId in which the uri is to be resolved.
7119     */
7120    @Override
7121    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
7122            final int modeFlags, int userId) {
7123        enforceNotIsolatedCaller("checkGrantUriPermission");
7124        synchronized(this) {
7125            return checkGrantUriPermissionLocked(callingUid, targetPkg,
7126                    new GrantUri(userId, uri, false), modeFlags, -1);
7127        }
7128    }
7129
7130    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
7131            final int modeFlags, UriPermissionOwner owner) {
7132        if (!Intent.isAccessUriMode(modeFlags)) {
7133            return;
7134        }
7135
7136        // So here we are: the caller has the assumed permission
7137        // to the uri, and the target doesn't.  Let's now give this to
7138        // the target.
7139
7140        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7141                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
7142
7143        final String authority = grantUri.uri.getAuthority();
7144        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7145        if (pi == null) {
7146            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
7147            return;
7148        }
7149
7150        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
7151            grantUri.prefix = true;
7152        }
7153        final UriPermission perm = findOrCreateUriPermissionLocked(
7154                pi.packageName, targetPkg, targetUid, grantUri);
7155        perm.grantModes(modeFlags, owner);
7156    }
7157
7158    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7159            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
7160        if (targetPkg == null) {
7161            throw new NullPointerException("targetPkg");
7162        }
7163        int targetUid;
7164        final IPackageManager pm = AppGlobals.getPackageManager();
7165        try {
7166            targetUid = pm.getPackageUid(targetPkg, targetUserId);
7167        } catch (RemoteException ex) {
7168            return;
7169        }
7170
7171        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
7172                targetUid);
7173        if (targetUid < 0) {
7174            return;
7175        }
7176
7177        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
7178                owner);
7179    }
7180
7181    static class NeededUriGrants extends ArrayList<GrantUri> {
7182        final String targetPkg;
7183        final int targetUid;
7184        final int flags;
7185
7186        NeededUriGrants(String targetPkg, int targetUid, int flags) {
7187            this.targetPkg = targetPkg;
7188            this.targetUid = targetUid;
7189            this.flags = flags;
7190        }
7191    }
7192
7193    /**
7194     * Like checkGrantUriPermissionLocked, but takes an Intent.
7195     */
7196    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
7197            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
7198        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7199                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
7200                + " clip=" + (intent != null ? intent.getClipData() : null)
7201                + " from " + intent + "; flags=0x"
7202                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
7203
7204        if (targetPkg == null) {
7205            throw new NullPointerException("targetPkg");
7206        }
7207
7208        if (intent == null) {
7209            return null;
7210        }
7211        Uri data = intent.getData();
7212        ClipData clip = intent.getClipData();
7213        if (data == null && clip == null) {
7214            return null;
7215        }
7216        // Default userId for uris in the intent (if they don't specify it themselves)
7217        int contentUserHint = intent.getContentUserHint();
7218        if (contentUserHint == UserHandle.USER_CURRENT) {
7219            contentUserHint = UserHandle.getUserId(callingUid);
7220        }
7221        final IPackageManager pm = AppGlobals.getPackageManager();
7222        int targetUid;
7223        if (needed != null) {
7224            targetUid = needed.targetUid;
7225        } else {
7226            try {
7227                targetUid = pm.getPackageUid(targetPkg, targetUserId);
7228            } catch (RemoteException ex) {
7229                return null;
7230            }
7231            if (targetUid < 0) {
7232                if (DEBUG_URI_PERMISSION) {
7233                    Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
7234                            + " on user " + targetUserId);
7235                }
7236                return null;
7237            }
7238        }
7239        if (data != null) {
7240            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
7241            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7242                    targetUid);
7243            if (targetUid > 0) {
7244                if (needed == null) {
7245                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
7246                }
7247                needed.add(grantUri);
7248            }
7249        }
7250        if (clip != null) {
7251            for (int i=0; i<clip.getItemCount(); i++) {
7252                Uri uri = clip.getItemAt(i).getUri();
7253                if (uri != null) {
7254                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
7255                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7256                            targetUid);
7257                    if (targetUid > 0) {
7258                        if (needed == null) {
7259                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
7260                        }
7261                        needed.add(grantUri);
7262                    }
7263                } else {
7264                    Intent clipIntent = clip.getItemAt(i).getIntent();
7265                    if (clipIntent != null) {
7266                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
7267                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
7268                        if (newNeeded != null) {
7269                            needed = newNeeded;
7270                        }
7271                    }
7272                }
7273            }
7274        }
7275
7276        return needed;
7277    }
7278
7279    /**
7280     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
7281     */
7282    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
7283            UriPermissionOwner owner) {
7284        if (needed != null) {
7285            for (int i=0; i<needed.size(); i++) {
7286                GrantUri grantUri = needed.get(i);
7287                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
7288                        grantUri, needed.flags, owner);
7289            }
7290        }
7291    }
7292
7293    void grantUriPermissionFromIntentLocked(int callingUid,
7294            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
7295        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
7296                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
7297        if (needed == null) {
7298            return;
7299        }
7300
7301        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
7302    }
7303
7304    /**
7305     * @param uri This uri must NOT contain an embedded userId.
7306     * @param userId The userId in which the uri is to be resolved.
7307     */
7308    @Override
7309    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
7310            final int modeFlags, int userId) {
7311        enforceNotIsolatedCaller("grantUriPermission");
7312        GrantUri grantUri = new GrantUri(userId, uri, false);
7313        synchronized(this) {
7314            final ProcessRecord r = getRecordForAppLocked(caller);
7315            if (r == null) {
7316                throw new SecurityException("Unable to find app for caller "
7317                        + caller
7318                        + " when granting permission to uri " + grantUri);
7319            }
7320            if (targetPkg == null) {
7321                throw new IllegalArgumentException("null target");
7322            }
7323            if (grantUri == null) {
7324                throw new IllegalArgumentException("null uri");
7325            }
7326
7327            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
7328                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
7329                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
7330                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
7331
7332            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
7333                    UserHandle.getUserId(r.uid));
7334        }
7335    }
7336
7337    void removeUriPermissionIfNeededLocked(UriPermission perm) {
7338        if (perm.modeFlags == 0) {
7339            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7340                    perm.targetUid);
7341            if (perms != null) {
7342                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7343                        "Removing " + perm.targetUid + " permission to " + perm.uri);
7344
7345                perms.remove(perm.uri);
7346                if (perms.isEmpty()) {
7347                    mGrantedUriPermissions.remove(perm.targetUid);
7348                }
7349            }
7350        }
7351    }
7352
7353    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
7354        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
7355
7356        final IPackageManager pm = AppGlobals.getPackageManager();
7357        final String authority = grantUri.uri.getAuthority();
7358        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7359        if (pi == null) {
7360            Slog.w(TAG, "No content provider found for permission revoke: "
7361                    + grantUri.toSafeString());
7362            return;
7363        }
7364
7365        // Does the caller have this permission on the URI?
7366        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7367            // If they don't have direct access to the URI, then revoke any
7368            // ownerless URI permissions that have been granted to them.
7369            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7370            if (perms != null) {
7371                boolean persistChanged = false;
7372                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7373                    final UriPermission perm = it.next();
7374                    if (perm.uri.sourceUserId == grantUri.sourceUserId
7375                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7376                        if (DEBUG_URI_PERMISSION)
7377                            Slog.v(TAG, "Revoking non-owned " + perm.targetUid +
7378                                    " permission to " + perm.uri);
7379                        persistChanged |= perm.revokeModes(
7380                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
7381                        if (perm.modeFlags == 0) {
7382                            it.remove();
7383                        }
7384                    }
7385                }
7386                if (perms.isEmpty()) {
7387                    mGrantedUriPermissions.remove(callingUid);
7388                }
7389                if (persistChanged) {
7390                    schedulePersistUriGrants();
7391                }
7392            }
7393            return;
7394        }
7395
7396        boolean persistChanged = false;
7397
7398        // Go through all of the permissions and remove any that match.
7399        int N = mGrantedUriPermissions.size();
7400        for (int i = 0; i < N; i++) {
7401            final int targetUid = mGrantedUriPermissions.keyAt(i);
7402            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7403
7404            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7405                final UriPermission perm = it.next();
7406                if (perm.uri.sourceUserId == grantUri.sourceUserId
7407                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7408                    if (DEBUG_URI_PERMISSION)
7409                        Slog.v(TAG,
7410                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
7411                    persistChanged |= perm.revokeModes(
7412                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7413                    if (perm.modeFlags == 0) {
7414                        it.remove();
7415                    }
7416                }
7417            }
7418
7419            if (perms.isEmpty()) {
7420                mGrantedUriPermissions.remove(targetUid);
7421                N--;
7422                i--;
7423            }
7424        }
7425
7426        if (persistChanged) {
7427            schedulePersistUriGrants();
7428        }
7429    }
7430
7431    /**
7432     * @param uri This uri must NOT contain an embedded userId.
7433     * @param userId The userId in which the uri is to be resolved.
7434     */
7435    @Override
7436    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
7437            int userId) {
7438        enforceNotIsolatedCaller("revokeUriPermission");
7439        synchronized(this) {
7440            final ProcessRecord r = getRecordForAppLocked(caller);
7441            if (r == null) {
7442                throw new SecurityException("Unable to find app for caller "
7443                        + caller
7444                        + " when revoking permission to uri " + uri);
7445            }
7446            if (uri == null) {
7447                Slog.w(TAG, "revokeUriPermission: null uri");
7448                return;
7449            }
7450
7451            if (!Intent.isAccessUriMode(modeFlags)) {
7452                return;
7453            }
7454
7455            final IPackageManager pm = AppGlobals.getPackageManager();
7456            final String authority = uri.getAuthority();
7457            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
7458            if (pi == null) {
7459                Slog.w(TAG, "No content provider found for permission revoke: "
7460                        + uri.toSafeString());
7461                return;
7462            }
7463
7464            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
7465        }
7466    }
7467
7468    /**
7469     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
7470     * given package.
7471     *
7472     * @param packageName Package name to match, or {@code null} to apply to all
7473     *            packages.
7474     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
7475     *            to all users.
7476     * @param persistable If persistable grants should be removed.
7477     */
7478    private void removeUriPermissionsForPackageLocked(
7479            String packageName, int userHandle, boolean persistable) {
7480        if (userHandle == UserHandle.USER_ALL && packageName == null) {
7481            throw new IllegalArgumentException("Must narrow by either package or user");
7482        }
7483
7484        boolean persistChanged = false;
7485
7486        int N = mGrantedUriPermissions.size();
7487        for (int i = 0; i < N; i++) {
7488            final int targetUid = mGrantedUriPermissions.keyAt(i);
7489            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7490
7491            // Only inspect grants matching user
7492            if (userHandle == UserHandle.USER_ALL
7493                    || userHandle == UserHandle.getUserId(targetUid)) {
7494                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7495                    final UriPermission perm = it.next();
7496
7497                    // Only inspect grants matching package
7498                    if (packageName == null || perm.sourcePkg.equals(packageName)
7499                            || perm.targetPkg.equals(packageName)) {
7500                        persistChanged |= perm.revokeModes(persistable
7501                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7502
7503                        // Only remove when no modes remain; any persisted grants
7504                        // will keep this alive.
7505                        if (perm.modeFlags == 0) {
7506                            it.remove();
7507                        }
7508                    }
7509                }
7510
7511                if (perms.isEmpty()) {
7512                    mGrantedUriPermissions.remove(targetUid);
7513                    N--;
7514                    i--;
7515                }
7516            }
7517        }
7518
7519        if (persistChanged) {
7520            schedulePersistUriGrants();
7521        }
7522    }
7523
7524    @Override
7525    public IBinder newUriPermissionOwner(String name) {
7526        enforceNotIsolatedCaller("newUriPermissionOwner");
7527        synchronized(this) {
7528            UriPermissionOwner owner = new UriPermissionOwner(this, name);
7529            return owner.getExternalTokenLocked();
7530        }
7531    }
7532
7533    /**
7534     * @param uri This uri must NOT contain an embedded userId.
7535     * @param sourceUserId The userId in which the uri is to be resolved.
7536     * @param targetUserId The userId of the app that receives the grant.
7537     */
7538    @Override
7539    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
7540            final int modeFlags, int sourceUserId, int targetUserId) {
7541        targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
7542                targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null);
7543        synchronized(this) {
7544            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7545            if (owner == null) {
7546                throw new IllegalArgumentException("Unknown owner: " + token);
7547            }
7548            if (fromUid != Binder.getCallingUid()) {
7549                if (Binder.getCallingUid() != Process.myUid()) {
7550                    // Only system code can grant URI permissions on behalf
7551                    // of other users.
7552                    throw new SecurityException("nice try");
7553                }
7554            }
7555            if (targetPkg == null) {
7556                throw new IllegalArgumentException("null target");
7557            }
7558            if (uri == null) {
7559                throw new IllegalArgumentException("null uri");
7560            }
7561
7562            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
7563                    modeFlags, owner, targetUserId);
7564        }
7565    }
7566
7567    /**
7568     * @param uri This uri must NOT contain an embedded userId.
7569     * @param userId The userId in which the uri is to be resolved.
7570     */
7571    @Override
7572    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
7573        synchronized(this) {
7574            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7575            if (owner == null) {
7576                throw new IllegalArgumentException("Unknown owner: " + token);
7577            }
7578
7579            if (uri == null) {
7580                owner.removeUriPermissionsLocked(mode);
7581            } else {
7582                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
7583            }
7584        }
7585    }
7586
7587    private void schedulePersistUriGrants() {
7588        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
7589            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
7590                    10 * DateUtils.SECOND_IN_MILLIS);
7591        }
7592    }
7593
7594    private void writeGrantedUriPermissions() {
7595        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
7596
7597        // Snapshot permissions so we can persist without lock
7598        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
7599        synchronized (this) {
7600            final int size = mGrantedUriPermissions.size();
7601            for (int i = 0; i < size; i++) {
7602                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7603                for (UriPermission perm : perms.values()) {
7604                    if (perm.persistedModeFlags != 0) {
7605                        persist.add(perm.snapshot());
7606                    }
7607                }
7608            }
7609        }
7610
7611        FileOutputStream fos = null;
7612        try {
7613            fos = mGrantFile.startWrite();
7614
7615            XmlSerializer out = new FastXmlSerializer();
7616            out.setOutput(fos, "utf-8");
7617            out.startDocument(null, true);
7618            out.startTag(null, TAG_URI_GRANTS);
7619            for (UriPermission.Snapshot perm : persist) {
7620                out.startTag(null, TAG_URI_GRANT);
7621                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
7622                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
7623                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
7624                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
7625                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
7626                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
7627                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
7628                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
7629                out.endTag(null, TAG_URI_GRANT);
7630            }
7631            out.endTag(null, TAG_URI_GRANTS);
7632            out.endDocument();
7633
7634            mGrantFile.finishWrite(fos);
7635        } catch (IOException e) {
7636            if (fos != null) {
7637                mGrantFile.failWrite(fos);
7638            }
7639        }
7640    }
7641
7642    private void readGrantedUriPermissionsLocked() {
7643        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
7644
7645        final long now = System.currentTimeMillis();
7646
7647        FileInputStream fis = null;
7648        try {
7649            fis = mGrantFile.openRead();
7650            final XmlPullParser in = Xml.newPullParser();
7651            in.setInput(fis, null);
7652
7653            int type;
7654            while ((type = in.next()) != END_DOCUMENT) {
7655                final String tag = in.getName();
7656                if (type == START_TAG) {
7657                    if (TAG_URI_GRANT.equals(tag)) {
7658                        final int sourceUserId;
7659                        final int targetUserId;
7660                        final int userHandle = readIntAttribute(in,
7661                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
7662                        if (userHandle != UserHandle.USER_NULL) {
7663                            // For backwards compatibility.
7664                            sourceUserId = userHandle;
7665                            targetUserId = userHandle;
7666                        } else {
7667                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
7668                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
7669                        }
7670                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
7671                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
7672                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
7673                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
7674                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
7675                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
7676
7677                        // Sanity check that provider still belongs to source package
7678                        final ProviderInfo pi = getProviderInfoLocked(
7679                                uri.getAuthority(), sourceUserId);
7680                        if (pi != null && sourcePkg.equals(pi.packageName)) {
7681                            int targetUid = -1;
7682                            try {
7683                                targetUid = AppGlobals.getPackageManager()
7684                                        .getPackageUid(targetPkg, targetUserId);
7685                            } catch (RemoteException e) {
7686                            }
7687                            if (targetUid != -1) {
7688                                final UriPermission perm = findOrCreateUriPermissionLocked(
7689                                        sourcePkg, targetPkg, targetUid,
7690                                        new GrantUri(sourceUserId, uri, prefix));
7691                                perm.initPersistedModes(modeFlags, createdTime);
7692                            }
7693                        } else {
7694                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
7695                                    + " but instead found " + pi);
7696                        }
7697                    }
7698                }
7699            }
7700        } catch (FileNotFoundException e) {
7701            // Missing grants is okay
7702        } catch (IOException e) {
7703            Slog.wtf(TAG, "Failed reading Uri grants", e);
7704        } catch (XmlPullParserException e) {
7705            Slog.wtf(TAG, "Failed reading Uri grants", e);
7706        } finally {
7707            IoUtils.closeQuietly(fis);
7708        }
7709    }
7710
7711    /**
7712     * @param uri This uri must NOT contain an embedded userId.
7713     * @param userId The userId in which the uri is to be resolved.
7714     */
7715    @Override
7716    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7717        enforceNotIsolatedCaller("takePersistableUriPermission");
7718
7719        Preconditions.checkFlagsArgument(modeFlags,
7720                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7721
7722        synchronized (this) {
7723            final int callingUid = Binder.getCallingUid();
7724            boolean persistChanged = false;
7725            GrantUri grantUri = new GrantUri(userId, uri, false);
7726
7727            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7728                    new GrantUri(userId, uri, false));
7729            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7730                    new GrantUri(userId, uri, true));
7731
7732            final boolean exactValid = (exactPerm != null)
7733                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
7734            final boolean prefixValid = (prefixPerm != null)
7735                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
7736
7737            if (!(exactValid || prefixValid)) {
7738                throw new SecurityException("No persistable permission grants found for UID "
7739                        + callingUid + " and Uri " + grantUri.toSafeString());
7740            }
7741
7742            if (exactValid) {
7743                persistChanged |= exactPerm.takePersistableModes(modeFlags);
7744            }
7745            if (prefixValid) {
7746                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
7747            }
7748
7749            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
7750
7751            if (persistChanged) {
7752                schedulePersistUriGrants();
7753            }
7754        }
7755    }
7756
7757    /**
7758     * @param uri This uri must NOT contain an embedded userId.
7759     * @param userId The userId in which the uri is to be resolved.
7760     */
7761    @Override
7762    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7763        enforceNotIsolatedCaller("releasePersistableUriPermission");
7764
7765        Preconditions.checkFlagsArgument(modeFlags,
7766                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7767
7768        synchronized (this) {
7769            final int callingUid = Binder.getCallingUid();
7770            boolean persistChanged = false;
7771
7772            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7773                    new GrantUri(userId, uri, false));
7774            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7775                    new GrantUri(userId, uri, true));
7776            if (exactPerm == null && prefixPerm == null) {
7777                throw new SecurityException("No permission grants found for UID " + callingUid
7778                        + " and Uri " + uri.toSafeString());
7779            }
7780
7781            if (exactPerm != null) {
7782                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
7783                removeUriPermissionIfNeededLocked(exactPerm);
7784            }
7785            if (prefixPerm != null) {
7786                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
7787                removeUriPermissionIfNeededLocked(prefixPerm);
7788            }
7789
7790            if (persistChanged) {
7791                schedulePersistUriGrants();
7792            }
7793        }
7794    }
7795
7796    /**
7797     * Prune any older {@link UriPermission} for the given UID until outstanding
7798     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
7799     *
7800     * @return if any mutations occured that require persisting.
7801     */
7802    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
7803        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7804        if (perms == null) return false;
7805        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
7806
7807        final ArrayList<UriPermission> persisted = Lists.newArrayList();
7808        for (UriPermission perm : perms.values()) {
7809            if (perm.persistedModeFlags != 0) {
7810                persisted.add(perm);
7811            }
7812        }
7813
7814        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
7815        if (trimCount <= 0) return false;
7816
7817        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
7818        for (int i = 0; i < trimCount; i++) {
7819            final UriPermission perm = persisted.get(i);
7820
7821            if (DEBUG_URI_PERMISSION) {
7822                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
7823            }
7824
7825            perm.releasePersistableModes(~0);
7826            removeUriPermissionIfNeededLocked(perm);
7827        }
7828
7829        return true;
7830    }
7831
7832    @Override
7833    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
7834            String packageName, boolean incoming) {
7835        enforceNotIsolatedCaller("getPersistedUriPermissions");
7836        Preconditions.checkNotNull(packageName, "packageName");
7837
7838        final int callingUid = Binder.getCallingUid();
7839        final IPackageManager pm = AppGlobals.getPackageManager();
7840        try {
7841            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
7842            if (packageUid != callingUid) {
7843                throw new SecurityException(
7844                        "Package " + packageName + " does not belong to calling UID " + callingUid);
7845            }
7846        } catch (RemoteException e) {
7847            throw new SecurityException("Failed to verify package name ownership");
7848        }
7849
7850        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
7851        synchronized (this) {
7852            if (incoming) {
7853                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7854                        callingUid);
7855                if (perms == null) {
7856                    Slog.w(TAG, "No permission grants found for " + packageName);
7857                } else {
7858                    for (UriPermission perm : perms.values()) {
7859                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
7860                            result.add(perm.buildPersistedPublicApiObject());
7861                        }
7862                    }
7863                }
7864            } else {
7865                final int size = mGrantedUriPermissions.size();
7866                for (int i = 0; i < size; i++) {
7867                    final ArrayMap<GrantUri, UriPermission> perms =
7868                            mGrantedUriPermissions.valueAt(i);
7869                    for (UriPermission perm : perms.values()) {
7870                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
7871                            result.add(perm.buildPersistedPublicApiObject());
7872                        }
7873                    }
7874                }
7875            }
7876        }
7877        return new ParceledListSlice<android.content.UriPermission>(result);
7878    }
7879
7880    @Override
7881    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
7882        synchronized (this) {
7883            ProcessRecord app =
7884                who != null ? getRecordForAppLocked(who) : null;
7885            if (app == null) return;
7886
7887            Message msg = Message.obtain();
7888            msg.what = WAIT_FOR_DEBUGGER_MSG;
7889            msg.obj = app;
7890            msg.arg1 = waiting ? 1 : 0;
7891            mHandler.sendMessage(msg);
7892        }
7893    }
7894
7895    @Override
7896    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
7897        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
7898        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
7899        outInfo.availMem = Process.getFreeMemory();
7900        outInfo.totalMem = Process.getTotalMemory();
7901        outInfo.threshold = homeAppMem;
7902        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
7903        outInfo.hiddenAppThreshold = cachedAppMem;
7904        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
7905                ProcessList.SERVICE_ADJ);
7906        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
7907                ProcessList.VISIBLE_APP_ADJ);
7908        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
7909                ProcessList.FOREGROUND_APP_ADJ);
7910    }
7911
7912    // =========================================================
7913    // TASK MANAGEMENT
7914    // =========================================================
7915
7916    @Override
7917    public List<IAppTask> getAppTasks(String callingPackage) {
7918        int callingUid = Binder.getCallingUid();
7919        long ident = Binder.clearCallingIdentity();
7920
7921        synchronized(this) {
7922            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
7923            try {
7924                if (localLOGV) Slog.v(TAG, "getAppTasks");
7925
7926                final int N = mRecentTasks.size();
7927                for (int i = 0; i < N; i++) {
7928                    TaskRecord tr = mRecentTasks.get(i);
7929                    // Skip tasks that do not match the caller.  We don't need to verify
7930                    // callingPackage, because we are also limiting to callingUid and know
7931                    // that will limit to the correct security sandbox.
7932                    if (tr.effectiveUid != callingUid) {
7933                        continue;
7934                    }
7935                    Intent intent = tr.getBaseIntent();
7936                    if (intent == null ||
7937                            !callingPackage.equals(intent.getComponent().getPackageName())) {
7938                        continue;
7939                    }
7940                    ActivityManager.RecentTaskInfo taskInfo =
7941                            createRecentTaskInfoFromTaskRecord(tr);
7942                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
7943                    list.add(taskImpl);
7944                }
7945            } finally {
7946                Binder.restoreCallingIdentity(ident);
7947            }
7948            return list;
7949        }
7950    }
7951
7952    @Override
7953    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
7954        final int callingUid = Binder.getCallingUid();
7955        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
7956
7957        synchronized(this) {
7958            if (localLOGV) Slog.v(
7959                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
7960
7961            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
7962                    callingUid);
7963
7964            // TODO: Improve with MRU list from all ActivityStacks.
7965            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
7966        }
7967
7968        return list;
7969    }
7970
7971    TaskRecord getMostRecentTask() {
7972        return mRecentTasks.get(0);
7973    }
7974
7975    /**
7976     * Creates a new RecentTaskInfo from a TaskRecord.
7977     */
7978    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
7979        // Update the task description to reflect any changes in the task stack
7980        tr.updateTaskDescription();
7981
7982        // Compose the recent task info
7983        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
7984        rti.id = tr.getTopActivity() == null ? -1 : tr.taskId;
7985        rti.persistentId = tr.taskId;
7986        rti.baseIntent = new Intent(tr.getBaseIntent());
7987        rti.origActivity = tr.origActivity;
7988        rti.description = tr.lastDescription;
7989        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
7990        rti.userId = tr.userId;
7991        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
7992        rti.firstActiveTime = tr.firstActiveTime;
7993        rti.lastActiveTime = tr.lastActiveTime;
7994        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
7995        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
7996        return rti;
7997    }
7998
7999    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
8000        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
8001                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
8002        if (!allowed) {
8003            if (checkPermission(android.Manifest.permission.GET_TASKS,
8004                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
8005                // Temporary compatibility: some existing apps on the system image may
8006                // still be requesting the old permission and not switched to the new
8007                // one; if so, we'll still allow them full access.  This means we need
8008                // to see if they are holding the old permission and are a system app.
8009                try {
8010                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
8011                        allowed = true;
8012                        Slog.w(TAG, caller + ": caller " + callingUid
8013                                + " is using old GET_TASKS but privileged; allowing");
8014                    }
8015                } catch (RemoteException e) {
8016                }
8017            }
8018        }
8019        if (!allowed) {
8020            Slog.w(TAG, caller + ": caller " + callingUid
8021                    + " does not hold GET_TASKS; limiting output");
8022        }
8023        return allowed;
8024    }
8025
8026    @Override
8027    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8028        final int callingUid = Binder.getCallingUid();
8029        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8030                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8031
8032        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8033        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8034        synchronized (this) {
8035            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
8036                    callingUid);
8037            final boolean detailed = checkCallingPermission(
8038                    android.Manifest.permission.GET_DETAILED_TASKS)
8039                    == PackageManager.PERMISSION_GRANTED;
8040
8041            final int N = mRecentTasks.size();
8042            ArrayList<ActivityManager.RecentTaskInfo> res
8043                    = new ArrayList<ActivityManager.RecentTaskInfo>(
8044                            maxNum < N ? maxNum : N);
8045
8046            final Set<Integer> includedUsers;
8047            if (includeProfiles) {
8048                includedUsers = getProfileIdsLocked(userId);
8049            } else {
8050                includedUsers = new HashSet<Integer>();
8051            }
8052            includedUsers.add(Integer.valueOf(userId));
8053
8054            for (int i=0; i<N && maxNum > 0; i++) {
8055                TaskRecord tr = mRecentTasks.get(i);
8056                // Only add calling user or related users recent tasks
8057                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
8058                    if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr);
8059                    continue;
8060                }
8061
8062                // Return the entry if desired by the caller.  We always return
8063                // the first entry, because callers always expect this to be the
8064                // foreground app.  We may filter others if the caller has
8065                // not supplied RECENT_WITH_EXCLUDED and there is some reason
8066                // we should exclude the entry.
8067
8068                if (i == 0
8069                        || withExcluded
8070                        || (tr.intent == null)
8071                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
8072                                == 0)) {
8073                    if (!allowed) {
8074                        // If the caller doesn't have the GET_TASKS permission, then only
8075                        // allow them to see a small subset of tasks -- their own and home.
8076                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
8077                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr);
8078                            continue;
8079                        }
8080                    }
8081                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
8082                        if (tr.stack != null && tr.stack.isHomeStack()) {
8083                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr);
8084                            continue;
8085                        }
8086                    }
8087                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
8088                        // Don't include auto remove tasks that are finished or finishing.
8089                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: "
8090                                + tr);
8091                        continue;
8092                    }
8093                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
8094                            && !tr.isAvailable) {
8095                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr);
8096                        continue;
8097                    }
8098
8099                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
8100                    if (!detailed) {
8101                        rti.baseIntent.replaceExtras((Bundle)null);
8102                    }
8103
8104                    res.add(rti);
8105                    maxNum--;
8106                }
8107            }
8108            return res;
8109        }
8110    }
8111
8112    private TaskRecord taskForIdLocked(int id) {
8113        final TaskRecord task = recentTaskForIdLocked(id);
8114        if (task != null) {
8115            return task;
8116        }
8117
8118        // Don't give up. Sometimes it just hasn't made it to recents yet.
8119        return mStackSupervisor.anyTaskForIdLocked(id);
8120    }
8121
8122    private TaskRecord recentTaskForIdLocked(int id) {
8123        final int N = mRecentTasks.size();
8124            for (int i=0; i<N; i++) {
8125                TaskRecord tr = mRecentTasks.get(i);
8126                if (tr.taskId == id) {
8127                    return tr;
8128                }
8129            }
8130            return null;
8131    }
8132
8133    @Override
8134    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
8135        synchronized (this) {
8136            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
8137                    "getTaskThumbnail()");
8138            TaskRecord tr = recentTaskForIdLocked(id);
8139            if (tr != null) {
8140                return tr.getTaskThumbnailLocked();
8141            }
8142        }
8143        return null;
8144    }
8145
8146    @Override
8147    public int addAppTask(IBinder activityToken, Intent intent,
8148            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
8149        final int callingUid = Binder.getCallingUid();
8150        final long callingIdent = Binder.clearCallingIdentity();
8151
8152        try {
8153            synchronized (this) {
8154                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8155                if (r == null) {
8156                    throw new IllegalArgumentException("Activity does not exist; token="
8157                            + activityToken);
8158                }
8159                ComponentName comp = intent.getComponent();
8160                if (comp == null) {
8161                    throw new IllegalArgumentException("Intent " + intent
8162                            + " must specify explicit component");
8163                }
8164                if (thumbnail.getWidth() != mThumbnailWidth
8165                        || thumbnail.getHeight() != mThumbnailHeight) {
8166                    throw new IllegalArgumentException("Bad thumbnail size: got "
8167                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
8168                            + mThumbnailWidth + "x" + mThumbnailHeight);
8169                }
8170                if (intent.getSelector() != null) {
8171                    intent.setSelector(null);
8172                }
8173                if (intent.getSourceBounds() != null) {
8174                    intent.setSourceBounds(null);
8175                }
8176                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
8177                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
8178                        // The caller has added this as an auto-remove task...  that makes no
8179                        // sense, so turn off auto-remove.
8180                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
8181                    }
8182                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
8183                    // Must be a new task.
8184                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8185                }
8186                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
8187                    mLastAddedTaskActivity = null;
8188                }
8189                ActivityInfo ainfo = mLastAddedTaskActivity;
8190                if (ainfo == null) {
8191                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
8192                            comp, 0, UserHandle.getUserId(callingUid));
8193                    if (ainfo.applicationInfo.uid != callingUid) {
8194                        throw new SecurityException(
8195                                "Can't add task for another application: target uid="
8196                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
8197                    }
8198                }
8199
8200                TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo,
8201                        intent, description);
8202
8203                int trimIdx = trimRecentsForTask(task, false);
8204                if (trimIdx >= 0) {
8205                    // If this would have caused a trim, then we'll abort because that
8206                    // means it would be added at the end of the list but then just removed.
8207                    return -1;
8208                }
8209
8210                final int N = mRecentTasks.size();
8211                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
8212                    final TaskRecord tr = mRecentTasks.remove(N - 1);
8213                    tr.removedFromRecents(mTaskPersister);
8214                }
8215
8216                task.inRecents = true;
8217                mRecentTasks.add(task);
8218                r.task.stack.addTask(task, false, false);
8219
8220                task.setLastThumbnail(thumbnail);
8221                task.freeLastThumbnail();
8222
8223                return task.taskId;
8224            }
8225        } finally {
8226            Binder.restoreCallingIdentity(callingIdent);
8227        }
8228    }
8229
8230    @Override
8231    public Point getAppTaskThumbnailSize() {
8232        synchronized (this) {
8233            return new Point(mThumbnailWidth,  mThumbnailHeight);
8234        }
8235    }
8236
8237    @Override
8238    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
8239        synchronized (this) {
8240            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8241            if (r != null) {
8242                r.setTaskDescription(td);
8243                r.task.updateTaskDescription();
8244            }
8245        }
8246    }
8247
8248    @Override
8249    public Bitmap getTaskDescriptionIcon(String filename) {
8250        if (!FileUtils.isValidExtFilename(filename)
8251                || !filename.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
8252            throw new IllegalArgumentException("Bad filename: " + filename);
8253        }
8254        return mTaskPersister.getTaskDescriptionIcon(filename);
8255    }
8256
8257    @Override
8258    public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
8259            throws RemoteException {
8260        if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
8261                opts.getCustomInPlaceResId() == 0) {
8262            throw new IllegalArgumentException("Expected in-place ActivityOption " +
8263                    "with valid animation");
8264        }
8265        mWindowManager.prepareAppTransition(AppTransition.TRANSIT_TASK_IN_PLACE, false);
8266        mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
8267                opts.getCustomInPlaceResId());
8268        mWindowManager.executeAppTransition();
8269    }
8270
8271    private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess) {
8272        mRecentTasks.remove(tr);
8273        tr.removedFromRecents(mTaskPersister);
8274        ComponentName component = tr.getBaseIntent().getComponent();
8275        if (component == null) {
8276            Slog.w(TAG, "No component for base intent of task: " + tr);
8277            return;
8278        }
8279
8280        if (!killProcess) {
8281            return;
8282        }
8283
8284        // Determine if the process(es) for this task should be killed.
8285        final String pkg = component.getPackageName();
8286        ArrayList<ProcessRecord> procsToKill = new ArrayList<ProcessRecord>();
8287        ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
8288        for (int i = 0; i < pmap.size(); i++) {
8289
8290            SparseArray<ProcessRecord> uids = pmap.valueAt(i);
8291            for (int j = 0; j < uids.size(); j++) {
8292                ProcessRecord proc = uids.valueAt(j);
8293                if (proc.userId != tr.userId) {
8294                    // Don't kill process for a different user.
8295                    continue;
8296                }
8297                if (proc == mHomeProcess) {
8298                    // Don't kill the home process along with tasks from the same package.
8299                    continue;
8300                }
8301                if (!proc.pkgList.containsKey(pkg)) {
8302                    // Don't kill process that is not associated with this task.
8303                    continue;
8304                }
8305
8306                for (int k = 0; k < proc.activities.size(); k++) {
8307                    TaskRecord otherTask = proc.activities.get(k).task;
8308                    if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
8309                        // Don't kill process(es) that has an activity in a different task that is
8310                        // also in recents.
8311                        return;
8312                    }
8313                }
8314
8315                // Add process to kill list.
8316                procsToKill.add(proc);
8317            }
8318        }
8319
8320        // Find any running services associated with this app and stop if needed.
8321        mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
8322
8323        // Kill the running processes.
8324        for (int i = 0; i < procsToKill.size(); i++) {
8325            ProcessRecord pr = procsToKill.get(i);
8326            if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
8327                pr.kill("remove task", true);
8328            } else {
8329                pr.waitingToKill = "remove task";
8330            }
8331        }
8332    }
8333
8334    private void removeTasksByPackageNameLocked(String packageName, int userId) {
8335        // Remove all tasks with activities in the specified package from the list of recent tasks
8336        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
8337            TaskRecord tr = mRecentTasks.get(i);
8338            if (tr.userId != userId) continue;
8339
8340            ComponentName cn = tr.intent.getComponent();
8341            if (cn != null && cn.getPackageName().equals(packageName)) {
8342                // If the package name matches, remove the task.
8343                removeTaskByIdLocked(tr.taskId, true);
8344            }
8345        }
8346    }
8347
8348    private void removeTasksByRemovedPackageComponentsLocked(String packageName, int userId) {
8349        final IPackageManager pm = AppGlobals.getPackageManager();
8350        final HashSet<ComponentName> componentsKnownToExist = new HashSet<ComponentName>();
8351
8352        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
8353            TaskRecord tr = mRecentTasks.get(i);
8354            if (tr.userId != userId) continue;
8355
8356            ComponentName cn = tr.intent.getComponent();
8357            if (cn != null && cn.getPackageName().equals(packageName)) {
8358                // Skip if component still exists in the package.
8359                if (componentsKnownToExist.contains(cn)) continue;
8360
8361                try {
8362                    ActivityInfo info = pm.getActivityInfo(cn, 0, userId);
8363                    if (info != null) {
8364                        componentsKnownToExist.add(cn);
8365                    } else {
8366                        removeTaskByIdLocked(tr.taskId, false);
8367                    }
8368                } catch (RemoteException e) {
8369                    Log.e(TAG, "Activity info query failed. component=" + cn, e);
8370                }
8371            }
8372        }
8373    }
8374
8375    /**
8376     * Removes the task with the specified task id.
8377     *
8378     * @param taskId Identifier of the task to be removed.
8379     * @param killProcess Kill any process associated with the task if possible.
8380     * @return Returns true if the given task was found and removed.
8381     */
8382    private boolean removeTaskByIdLocked(int taskId, boolean killProcess) {
8383        TaskRecord tr = taskForIdLocked(taskId);
8384        if (tr != null) {
8385            tr.removeTaskActivitiesLocked();
8386            cleanUpRemovedTaskLocked(tr, killProcess);
8387            if (tr.isPersistable) {
8388                notifyTaskPersisterLocked(null, true);
8389            }
8390            return true;
8391        }
8392        Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
8393        return false;
8394    }
8395
8396    @Override
8397    public boolean removeTask(int taskId) {
8398        synchronized (this) {
8399            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
8400                    "removeTask()");
8401            long ident = Binder.clearCallingIdentity();
8402            try {
8403                return removeTaskByIdLocked(taskId, true);
8404            } finally {
8405                Binder.restoreCallingIdentity(ident);
8406            }
8407        }
8408    }
8409
8410    /**
8411     * TODO: Add mController hook
8412     */
8413    @Override
8414    public void moveTaskToFront(int taskId, int flags, Bundle options) {
8415        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8416                "moveTaskToFront()");
8417
8418        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
8419        synchronized(this) {
8420            moveTaskToFrontLocked(taskId, flags, options);
8421        }
8422    }
8423
8424    void moveTaskToFrontLocked(int taskId, int flags, Bundle options) {
8425        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8426                Binder.getCallingUid(), -1, -1, "Task to front")) {
8427            ActivityOptions.abort(options);
8428            return;
8429        }
8430        final long origId = Binder.clearCallingIdentity();
8431        try {
8432            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8433            if (task == null) {
8434                Slog.d(TAG, "Could not find task for id: "+ taskId);
8435                return;
8436            }
8437            if (mStackSupervisor.isLockTaskModeViolation(task)) {
8438                mStackSupervisor.showLockTaskToast();
8439                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
8440                return;
8441            }
8442            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
8443            if (prev != null && prev.isRecentsActivity()) {
8444                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
8445            }
8446            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
8447        } finally {
8448            Binder.restoreCallingIdentity(origId);
8449        }
8450        ActivityOptions.abort(options);
8451    }
8452
8453    @Override
8454    public void moveTaskToBack(int taskId) {
8455        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8456                "moveTaskToBack()");
8457
8458        synchronized(this) {
8459            TaskRecord tr = taskForIdLocked(taskId);
8460            if (tr != null) {
8461                if (tr == mStackSupervisor.mLockTaskModeTask) {
8462                    mStackSupervisor.showLockTaskToast();
8463                    return;
8464                }
8465                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
8466                ActivityStack stack = tr.stack;
8467                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
8468                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8469                            Binder.getCallingUid(), -1, -1, "Task to back")) {
8470                        return;
8471                    }
8472                }
8473                final long origId = Binder.clearCallingIdentity();
8474                try {
8475                    stack.moveTaskToBackLocked(taskId, null);
8476                } finally {
8477                    Binder.restoreCallingIdentity(origId);
8478                }
8479            }
8480        }
8481    }
8482
8483    /**
8484     * Moves an activity, and all of the other activities within the same task, to the bottom
8485     * of the history stack.  The activity's order within the task is unchanged.
8486     *
8487     * @param token A reference to the activity we wish to move
8488     * @param nonRoot If false then this only works if the activity is the root
8489     *                of a task; if true it will work for any activity in a task.
8490     * @return Returns true if the move completed, false if not.
8491     */
8492    @Override
8493    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
8494        enforceNotIsolatedCaller("moveActivityTaskToBack");
8495        synchronized(this) {
8496            final long origId = Binder.clearCallingIdentity();
8497            try {
8498                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
8499                if (taskId >= 0) {
8500                    if ((mStackSupervisor.mLockTaskModeTask != null)
8501                            && (mStackSupervisor.mLockTaskModeTask.taskId == taskId)) {
8502                        mStackSupervisor.showLockTaskToast();
8503                        return false;
8504                    }
8505                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
8506                }
8507            } finally {
8508                Binder.restoreCallingIdentity(origId);
8509            }
8510        }
8511        return false;
8512    }
8513
8514    @Override
8515    public void moveTaskBackwards(int task) {
8516        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8517                "moveTaskBackwards()");
8518
8519        synchronized(this) {
8520            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8521                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
8522                return;
8523            }
8524            final long origId = Binder.clearCallingIdentity();
8525            moveTaskBackwardsLocked(task);
8526            Binder.restoreCallingIdentity(origId);
8527        }
8528    }
8529
8530    private final void moveTaskBackwardsLocked(int task) {
8531        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
8532    }
8533
8534    @Override
8535    public IBinder getHomeActivityToken() throws RemoteException {
8536        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8537                "getHomeActivityToken()");
8538        synchronized (this) {
8539            return mStackSupervisor.getHomeActivityToken();
8540        }
8541    }
8542
8543    @Override
8544    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
8545            IActivityContainerCallback callback) throws RemoteException {
8546        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8547                "createActivityContainer()");
8548        synchronized (this) {
8549            if (parentActivityToken == null) {
8550                throw new IllegalArgumentException("parent token must not be null");
8551            }
8552            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
8553            if (r == null) {
8554                return null;
8555            }
8556            if (callback == null) {
8557                throw new IllegalArgumentException("callback must not be null");
8558            }
8559            return mStackSupervisor.createActivityContainer(r, callback);
8560        }
8561    }
8562
8563    @Override
8564    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
8565        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8566                "deleteActivityContainer()");
8567        synchronized (this) {
8568            mStackSupervisor.deleteActivityContainer(container);
8569        }
8570    }
8571
8572    @Override
8573    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
8574            throws RemoteException {
8575        synchronized (this) {
8576            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
8577            if (stack != null) {
8578                return stack.mActivityContainer;
8579            }
8580            return null;
8581        }
8582    }
8583
8584    @Override
8585    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
8586        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8587                "moveTaskToStack()");
8588        if (stackId == HOME_STACK_ID) {
8589            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
8590                    new RuntimeException("here").fillInStackTrace());
8591        }
8592        synchronized (this) {
8593            long ident = Binder.clearCallingIdentity();
8594            try {
8595                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
8596                        + stackId + " toTop=" + toTop);
8597                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
8598            } finally {
8599                Binder.restoreCallingIdentity(ident);
8600            }
8601        }
8602    }
8603
8604    @Override
8605    public void resizeStack(int stackBoxId, Rect bounds) {
8606        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8607                "resizeStackBox()");
8608        long ident = Binder.clearCallingIdentity();
8609        try {
8610            mWindowManager.resizeStack(stackBoxId, bounds);
8611        } finally {
8612            Binder.restoreCallingIdentity(ident);
8613        }
8614    }
8615
8616    @Override
8617    public List<StackInfo> getAllStackInfos() {
8618        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8619                "getAllStackInfos()");
8620        long ident = Binder.clearCallingIdentity();
8621        try {
8622            synchronized (this) {
8623                return mStackSupervisor.getAllStackInfosLocked();
8624            }
8625        } finally {
8626            Binder.restoreCallingIdentity(ident);
8627        }
8628    }
8629
8630    @Override
8631    public StackInfo getStackInfo(int stackId) {
8632        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8633                "getStackInfo()");
8634        long ident = Binder.clearCallingIdentity();
8635        try {
8636            synchronized (this) {
8637                return mStackSupervisor.getStackInfoLocked(stackId);
8638            }
8639        } finally {
8640            Binder.restoreCallingIdentity(ident);
8641        }
8642    }
8643
8644    @Override
8645    public boolean isInHomeStack(int taskId) {
8646        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8647                "getStackInfo()");
8648        long ident = Binder.clearCallingIdentity();
8649        try {
8650            synchronized (this) {
8651                TaskRecord tr = taskForIdLocked(taskId);
8652                return tr != null && tr.stack != null && tr.stack.isHomeStack();
8653            }
8654        } finally {
8655            Binder.restoreCallingIdentity(ident);
8656        }
8657    }
8658
8659    @Override
8660    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
8661        synchronized(this) {
8662            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
8663        }
8664    }
8665
8666    private boolean isLockTaskAuthorized(String pkg) {
8667        final DevicePolicyManager dpm = (DevicePolicyManager)
8668                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
8669        try {
8670            int uid = mContext.getPackageManager().getPackageUid(pkg,
8671                    Binder.getCallingUserHandle().getIdentifier());
8672            return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
8673        } catch (NameNotFoundException e) {
8674            return false;
8675        }
8676    }
8677
8678    void startLockTaskMode(TaskRecord task) {
8679        final String pkg;
8680        synchronized (this) {
8681            pkg = task.intent.getComponent().getPackageName();
8682        }
8683        boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID;
8684        if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) {
8685            StatusBarManagerInternal statusBarManager = LocalServices.getService(
8686                    StatusBarManagerInternal.class);
8687            if (statusBarManager != null) {
8688                statusBarManager.showScreenPinningRequest();
8689            }
8690            return;
8691        }
8692        long ident = Binder.clearCallingIdentity();
8693        try {
8694            synchronized (this) {
8695                // Since we lost lock on task, make sure it is still there.
8696                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
8697                if (task != null) {
8698                    if (!isSystemInitiated
8699                            && ((mStackSupervisor.getFocusedStack() == null)
8700                                    || (task != mStackSupervisor.getFocusedStack().topTask()))) {
8701                        throw new IllegalArgumentException("Invalid task, not in foreground");
8702                    }
8703                    mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated);
8704                }
8705            }
8706        } finally {
8707            Binder.restoreCallingIdentity(ident);
8708        }
8709    }
8710
8711    @Override
8712    public void startLockTaskMode(int taskId) {
8713        final TaskRecord task;
8714        long ident = Binder.clearCallingIdentity();
8715        try {
8716            synchronized (this) {
8717                task = mStackSupervisor.anyTaskForIdLocked(taskId);
8718            }
8719        } finally {
8720            Binder.restoreCallingIdentity(ident);
8721        }
8722        if (task != null) {
8723            startLockTaskMode(task);
8724        }
8725    }
8726
8727    @Override
8728    public void startLockTaskMode(IBinder token) {
8729        final TaskRecord task;
8730        long ident = Binder.clearCallingIdentity();
8731        try {
8732            synchronized (this) {
8733                final ActivityRecord r = ActivityRecord.forToken(token);
8734                if (r == null) {
8735                    return;
8736                }
8737                task = r.task;
8738            }
8739        } finally {
8740            Binder.restoreCallingIdentity(ident);
8741        }
8742        if (task != null) {
8743            startLockTaskMode(task);
8744        }
8745    }
8746
8747    @Override
8748    public void startLockTaskModeOnCurrent() throws RemoteException {
8749        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8750                "startLockTaskModeOnCurrent");
8751        long ident = Binder.clearCallingIdentity();
8752        try {
8753            ActivityRecord r = null;
8754            synchronized (this) {
8755                r = mStackSupervisor.topRunningActivityLocked();
8756            }
8757            startLockTaskMode(r.task);
8758        } finally {
8759            Binder.restoreCallingIdentity(ident);
8760        }
8761    }
8762
8763    @Override
8764    public void stopLockTaskMode() {
8765        // Verify that the user matches the package of the intent for the TaskRecord
8766        // we are locked to or systtem.  This will ensure the same caller for startLockTaskMode
8767        // and stopLockTaskMode.
8768        final int callingUid = Binder.getCallingUid();
8769        if (callingUid != Process.SYSTEM_UID) {
8770            try {
8771                String pkg =
8772                        mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName();
8773                int uid = mContext.getPackageManager().getPackageUid(pkg,
8774                        Binder.getCallingUserHandle().getIdentifier());
8775                if (uid != callingUid) {
8776                    throw new SecurityException("Invalid uid, expected " + uid);
8777                }
8778            } catch (NameNotFoundException e) {
8779                Log.d(TAG, "stopLockTaskMode " + e);
8780                return;
8781            }
8782        }
8783        long ident = Binder.clearCallingIdentity();
8784        try {
8785            Log.d(TAG, "stopLockTaskMode");
8786            // Stop lock task
8787            synchronized (this) {
8788                mStackSupervisor.setLockTaskModeLocked(null, false);
8789            }
8790        } finally {
8791            Binder.restoreCallingIdentity(ident);
8792        }
8793    }
8794
8795    @Override
8796    public void stopLockTaskModeOnCurrent() throws RemoteException {
8797        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8798                "stopLockTaskModeOnCurrent");
8799        long ident = Binder.clearCallingIdentity();
8800        try {
8801            stopLockTaskMode();
8802        } finally {
8803            Binder.restoreCallingIdentity(ident);
8804        }
8805    }
8806
8807    @Override
8808    public boolean isInLockTaskMode() {
8809        synchronized (this) {
8810            return mStackSupervisor.isInLockTaskMode();
8811        }
8812    }
8813
8814    // =========================================================
8815    // CONTENT PROVIDERS
8816    // =========================================================
8817
8818    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
8819        List<ProviderInfo> providers = null;
8820        try {
8821            providers = AppGlobals.getPackageManager().
8822                queryContentProviders(app.processName, app.uid,
8823                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
8824        } catch (RemoteException ex) {
8825        }
8826        if (DEBUG_MU)
8827            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
8828        int userId = app.userId;
8829        if (providers != null) {
8830            int N = providers.size();
8831            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
8832            for (int i=0; i<N; i++) {
8833                ProviderInfo cpi =
8834                    (ProviderInfo)providers.get(i);
8835                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8836                        cpi.name, cpi.flags);
8837                if (singleton && UserHandle.getUserId(app.uid) != 0) {
8838                    // This is a singleton provider, but a user besides the
8839                    // default user is asking to initialize a process it runs
8840                    // in...  well, no, it doesn't actually run in this process,
8841                    // it runs in the process of the default user.  Get rid of it.
8842                    providers.remove(i);
8843                    N--;
8844                    i--;
8845                    continue;
8846                }
8847
8848                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8849                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
8850                if (cpr == null) {
8851                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
8852                    mProviderMap.putProviderByClass(comp, cpr);
8853                }
8854                if (DEBUG_MU)
8855                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
8856                app.pubProviders.put(cpi.name, cpr);
8857                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
8858                    // Don't add this if it is a platform component that is marked
8859                    // to run in multiple processes, because this is actually
8860                    // part of the framework so doesn't make sense to track as a
8861                    // separate apk in the process.
8862                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
8863                            mProcessStats);
8864                }
8865                ensurePackageDexOpt(cpi.applicationInfo.packageName);
8866            }
8867        }
8868        return providers;
8869    }
8870
8871    /**
8872     * Check if {@link ProcessRecord} has a possible chance at accessing the
8873     * given {@link ProviderInfo}. Final permission checking is always done
8874     * in {@link ContentProvider}.
8875     */
8876    private final String checkContentProviderPermissionLocked(
8877            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
8878        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
8879        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
8880        boolean checkedGrants = false;
8881        if (checkUser) {
8882            // Looking for cross-user grants before enforcing the typical cross-users permissions
8883            int tmpTargetUserId = unsafeConvertIncomingUser(userId);
8884            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
8885                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
8886                    return null;
8887                }
8888                checkedGrants = true;
8889            }
8890            userId = handleIncomingUser(callingPid, callingUid, userId,
8891                    false, ALLOW_NON_FULL,
8892                    "checkContentProviderPermissionLocked " + cpi.authority, null);
8893            if (userId != tmpTargetUserId) {
8894                // When we actually went to determine the final targer user ID, this ended
8895                // up different than our initial check for the authority.  This is because
8896                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
8897                // SELF.  So we need to re-check the grants again.
8898                checkedGrants = false;
8899            }
8900        }
8901        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
8902                cpi.applicationInfo.uid, cpi.exported)
8903                == PackageManager.PERMISSION_GRANTED) {
8904            return null;
8905        }
8906        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
8907                cpi.applicationInfo.uid, cpi.exported)
8908                == PackageManager.PERMISSION_GRANTED) {
8909            return null;
8910        }
8911
8912        PathPermission[] pps = cpi.pathPermissions;
8913        if (pps != null) {
8914            int i = pps.length;
8915            while (i > 0) {
8916                i--;
8917                PathPermission pp = pps[i];
8918                String pprperm = pp.getReadPermission();
8919                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
8920                        cpi.applicationInfo.uid, cpi.exported)
8921                        == PackageManager.PERMISSION_GRANTED) {
8922                    return null;
8923                }
8924                String ppwperm = pp.getWritePermission();
8925                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
8926                        cpi.applicationInfo.uid, cpi.exported)
8927                        == PackageManager.PERMISSION_GRANTED) {
8928                    return null;
8929                }
8930            }
8931        }
8932        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
8933            return null;
8934        }
8935
8936        String msg;
8937        if (!cpi.exported) {
8938            msg = "Permission Denial: opening provider " + cpi.name
8939                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8940                    + ", uid=" + callingUid + ") that is not exported from uid "
8941                    + cpi.applicationInfo.uid;
8942        } else {
8943            msg = "Permission Denial: opening provider " + cpi.name
8944                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8945                    + ", uid=" + callingUid + ") requires "
8946                    + cpi.readPermission + " or " + cpi.writePermission;
8947        }
8948        Slog.w(TAG, msg);
8949        return msg;
8950    }
8951
8952    /**
8953     * Returns if the ContentProvider has granted a uri to callingUid
8954     */
8955    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
8956        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8957        if (perms != null) {
8958            for (int i=perms.size()-1; i>=0; i--) {
8959                GrantUri grantUri = perms.keyAt(i);
8960                if (grantUri.sourceUserId == userId || !checkUser) {
8961                    if (matchesProvider(grantUri.uri, cpi)) {
8962                        return true;
8963                    }
8964                }
8965            }
8966        }
8967        return false;
8968    }
8969
8970    /**
8971     * Returns true if the uri authority is one of the authorities specified in the provider.
8972     */
8973    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
8974        String uriAuth = uri.getAuthority();
8975        String cpiAuth = cpi.authority;
8976        if (cpiAuth.indexOf(';') == -1) {
8977            return cpiAuth.equals(uriAuth);
8978        }
8979        String[] cpiAuths = cpiAuth.split(";");
8980        int length = cpiAuths.length;
8981        for (int i = 0; i < length; i++) {
8982            if (cpiAuths[i].equals(uriAuth)) return true;
8983        }
8984        return false;
8985    }
8986
8987    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
8988            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8989        if (r != null) {
8990            for (int i=0; i<r.conProviders.size(); i++) {
8991                ContentProviderConnection conn = r.conProviders.get(i);
8992                if (conn.provider == cpr) {
8993                    if (DEBUG_PROVIDER) Slog.v(TAG,
8994                            "Adding provider requested by "
8995                            + r.processName + " from process "
8996                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8997                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8998                    if (stable) {
8999                        conn.stableCount++;
9000                        conn.numStableIncs++;
9001                    } else {
9002                        conn.unstableCount++;
9003                        conn.numUnstableIncs++;
9004                    }
9005                    return conn;
9006                }
9007            }
9008            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
9009            if (stable) {
9010                conn.stableCount = 1;
9011                conn.numStableIncs = 1;
9012            } else {
9013                conn.unstableCount = 1;
9014                conn.numUnstableIncs = 1;
9015            }
9016            cpr.connections.add(conn);
9017            r.conProviders.add(conn);
9018            return conn;
9019        }
9020        cpr.addExternalProcessHandleLocked(externalProcessToken);
9021        return null;
9022    }
9023
9024    boolean decProviderCountLocked(ContentProviderConnection conn,
9025            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9026        if (conn != null) {
9027            cpr = conn.provider;
9028            if (DEBUG_PROVIDER) Slog.v(TAG,
9029                    "Removing provider requested by "
9030                    + conn.client.processName + " from process "
9031                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9032                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9033            if (stable) {
9034                conn.stableCount--;
9035            } else {
9036                conn.unstableCount--;
9037            }
9038            if (conn.stableCount == 0 && conn.unstableCount == 0) {
9039                cpr.connections.remove(conn);
9040                conn.client.conProviders.remove(conn);
9041                return true;
9042            }
9043            return false;
9044        }
9045        cpr.removeExternalProcessHandleLocked(externalProcessToken);
9046        return false;
9047    }
9048
9049    private void checkTime(long startTime, String where) {
9050        long now = SystemClock.elapsedRealtime();
9051        if ((now-startTime) > 1000) {
9052            // If we are taking more than a second, log about it.
9053            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
9054        }
9055    }
9056
9057    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
9058            String name, IBinder token, boolean stable, int userId) {
9059        ContentProviderRecord cpr;
9060        ContentProviderConnection conn = null;
9061        ProviderInfo cpi = null;
9062
9063        synchronized(this) {
9064            long startTime = SystemClock.elapsedRealtime();
9065
9066            ProcessRecord r = null;
9067            if (caller != null) {
9068                r = getRecordForAppLocked(caller);
9069                if (r == null) {
9070                    throw new SecurityException(
9071                            "Unable to find app for caller " + caller
9072                          + " (pid=" + Binder.getCallingPid()
9073                          + ") when getting content provider " + name);
9074                }
9075            }
9076
9077            boolean checkCrossUser = true;
9078
9079            checkTime(startTime, "getContentProviderImpl: getProviderByName");
9080
9081            // First check if this content provider has been published...
9082            cpr = mProviderMap.getProviderByName(name, userId);
9083            // If that didn't work, check if it exists for user 0 and then
9084            // verify that it's a singleton provider before using it.
9085            if (cpr == null && userId != UserHandle.USER_OWNER) {
9086                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
9087                if (cpr != null) {
9088                    cpi = cpr.info;
9089                    if (isSingleton(cpi.processName, cpi.applicationInfo,
9090                            cpi.name, cpi.flags)
9091                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
9092                        userId = UserHandle.USER_OWNER;
9093                        checkCrossUser = false;
9094                    } else {
9095                        cpr = null;
9096                        cpi = null;
9097                    }
9098                }
9099            }
9100
9101            boolean providerRunning = cpr != null;
9102            if (providerRunning) {
9103                cpi = cpr.info;
9104                String msg;
9105                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9106                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
9107                        != null) {
9108                    throw new SecurityException(msg);
9109                }
9110                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9111
9112                if (r != null && cpr.canRunHere(r)) {
9113                    // This provider has been published or is in the process
9114                    // of being published...  but it is also allowed to run
9115                    // in the caller's process, so don't make a connection
9116                    // and just let the caller instantiate its own instance.
9117                    ContentProviderHolder holder = cpr.newHolder(null);
9118                    // don't give caller the provider object, it needs
9119                    // to make its own.
9120                    holder.provider = null;
9121                    return holder;
9122                }
9123
9124                final long origId = Binder.clearCallingIdentity();
9125
9126                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
9127
9128                // In this case the provider instance already exists, so we can
9129                // return it right away.
9130                conn = incProviderCountLocked(r, cpr, token, stable);
9131                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
9132                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
9133                        // If this is a perceptible app accessing the provider,
9134                        // make sure to count it as being accessed and thus
9135                        // back up on the LRU list.  This is good because
9136                        // content providers are often expensive to start.
9137                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
9138                        updateLruProcessLocked(cpr.proc, false, null);
9139                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
9140                    }
9141                }
9142
9143                if (cpr.proc != null) {
9144                    if (false) {
9145                        if (cpr.name.flattenToShortString().equals(
9146                                "com.android.providers.calendar/.CalendarProvider2")) {
9147                            Slog.v(TAG, "****************** KILLING "
9148                                + cpr.name.flattenToShortString());
9149                            Process.killProcess(cpr.proc.pid);
9150                        }
9151                    }
9152                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
9153                    boolean success = updateOomAdjLocked(cpr.proc);
9154                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
9155                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
9156                    // NOTE: there is still a race here where a signal could be
9157                    // pending on the process even though we managed to update its
9158                    // adj level.  Not sure what to do about this, but at least
9159                    // the race is now smaller.
9160                    if (!success) {
9161                        // Uh oh...  it looks like the provider's process
9162                        // has been killed on us.  We need to wait for a new
9163                        // process to be started, and make sure its death
9164                        // doesn't kill our process.
9165                        Slog.i(TAG,
9166                                "Existing provider " + cpr.name.flattenToShortString()
9167                                + " is crashing; detaching " + r);
9168                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
9169                        checkTime(startTime, "getContentProviderImpl: before appDied");
9170                        appDiedLocked(cpr.proc);
9171                        checkTime(startTime, "getContentProviderImpl: after appDied");
9172                        if (!lastRef) {
9173                            // This wasn't the last ref our process had on
9174                            // the provider...  we have now been killed, bail.
9175                            return null;
9176                        }
9177                        providerRunning = false;
9178                        conn = null;
9179                    }
9180                }
9181
9182                Binder.restoreCallingIdentity(origId);
9183            }
9184
9185            boolean singleton;
9186            if (!providerRunning) {
9187                try {
9188                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
9189                    cpi = AppGlobals.getPackageManager().
9190                        resolveContentProvider(name,
9191                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
9192                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
9193                } catch (RemoteException ex) {
9194                }
9195                if (cpi == null) {
9196                    return null;
9197                }
9198                // If the provider is a singleton AND
9199                // (it's a call within the same user || the provider is a
9200                // privileged app)
9201                // Then allow connecting to the singleton provider
9202                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9203                        cpi.name, cpi.flags)
9204                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
9205                if (singleton) {
9206                    userId = UserHandle.USER_OWNER;
9207                }
9208                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
9209                checkTime(startTime, "getContentProviderImpl: got app info for user");
9210
9211                String msg;
9212                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9213                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
9214                        != null) {
9215                    throw new SecurityException(msg);
9216                }
9217                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9218
9219                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
9220                        && !cpi.processName.equals("system")) {
9221                    // If this content provider does not run in the system
9222                    // process, and the system is not yet ready to run other
9223                    // processes, then fail fast instead of hanging.
9224                    throw new IllegalArgumentException(
9225                            "Attempt to launch content provider before system ready");
9226                }
9227
9228                // Make sure that the user who owns this provider is started.  If not,
9229                // we don't want to allow it to run.
9230                if (mStartedUsers.get(userId) == null) {
9231                    Slog.w(TAG, "Unable to launch app "
9232                            + cpi.applicationInfo.packageName + "/"
9233                            + cpi.applicationInfo.uid + " for provider "
9234                            + name + ": user " + userId + " is stopped");
9235                    return null;
9236                }
9237
9238                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9239                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
9240                cpr = mProviderMap.getProviderByClass(comp, userId);
9241                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
9242                final boolean firstClass = cpr == null;
9243                if (firstClass) {
9244                    final long ident = Binder.clearCallingIdentity();
9245                    try {
9246                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
9247                        ApplicationInfo ai =
9248                            AppGlobals.getPackageManager().
9249                                getApplicationInfo(
9250                                        cpi.applicationInfo.packageName,
9251                                        STOCK_PM_FLAGS, userId);
9252                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
9253                        if (ai == null) {
9254                            Slog.w(TAG, "No package info for content provider "
9255                                    + cpi.name);
9256                            return null;
9257                        }
9258                        ai = getAppInfoForUser(ai, userId);
9259                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
9260                    } catch (RemoteException ex) {
9261                        // pm is in same process, this will never happen.
9262                    } finally {
9263                        Binder.restoreCallingIdentity(ident);
9264                    }
9265                }
9266
9267                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
9268
9269                if (r != null && cpr.canRunHere(r)) {
9270                    // If this is a multiprocess provider, then just return its
9271                    // info and allow the caller to instantiate it.  Only do
9272                    // this if the provider is the same user as the caller's
9273                    // process, or can run as root (so can be in any process).
9274                    return cpr.newHolder(null);
9275                }
9276
9277                if (DEBUG_PROVIDER) {
9278                    RuntimeException e = new RuntimeException("here");
9279                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
9280                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
9281                }
9282
9283                // This is single process, and our app is now connecting to it.
9284                // See if we are already in the process of launching this
9285                // provider.
9286                final int N = mLaunchingProviders.size();
9287                int i;
9288                for (i=0; i<N; i++) {
9289                    if (mLaunchingProviders.get(i) == cpr) {
9290                        break;
9291                    }
9292                }
9293
9294                // If the provider is not already being launched, then get it
9295                // started.
9296                if (i >= N) {
9297                    final long origId = Binder.clearCallingIdentity();
9298
9299                    try {
9300                        // Content provider is now in use, its package can't be stopped.
9301                        try {
9302                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
9303                            AppGlobals.getPackageManager().setPackageStoppedState(
9304                                    cpr.appInfo.packageName, false, userId);
9305                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
9306                        } catch (RemoteException e) {
9307                        } catch (IllegalArgumentException e) {
9308                            Slog.w(TAG, "Failed trying to unstop package "
9309                                    + cpr.appInfo.packageName + ": " + e);
9310                        }
9311
9312                        // Use existing process if already started
9313                        checkTime(startTime, "getContentProviderImpl: looking for process record");
9314                        ProcessRecord proc = getProcessRecordLocked(
9315                                cpi.processName, cpr.appInfo.uid, false);
9316                        if (proc != null && proc.thread != null) {
9317                            if (DEBUG_PROVIDER) {
9318                                Slog.d(TAG, "Installing in existing process " + proc);
9319                            }
9320                            checkTime(startTime, "getContentProviderImpl: scheduling install");
9321                            proc.pubProviders.put(cpi.name, cpr);
9322                            try {
9323                                proc.thread.scheduleInstallProvider(cpi);
9324                            } catch (RemoteException e) {
9325                            }
9326                        } else {
9327                            checkTime(startTime, "getContentProviderImpl: before start process");
9328                            proc = startProcessLocked(cpi.processName,
9329                                    cpr.appInfo, false, 0, "content provider",
9330                                    new ComponentName(cpi.applicationInfo.packageName,
9331                                            cpi.name), false, false, false);
9332                            checkTime(startTime, "getContentProviderImpl: after start process");
9333                            if (proc == null) {
9334                                Slog.w(TAG, "Unable to launch app "
9335                                        + cpi.applicationInfo.packageName + "/"
9336                                        + cpi.applicationInfo.uid + " for provider "
9337                                        + name + ": process is bad");
9338                                return null;
9339                            }
9340                        }
9341                        cpr.launchingApp = proc;
9342                        mLaunchingProviders.add(cpr);
9343                    } finally {
9344                        Binder.restoreCallingIdentity(origId);
9345                    }
9346                }
9347
9348                checkTime(startTime, "getContentProviderImpl: updating data structures");
9349
9350                // Make sure the provider is published (the same provider class
9351                // may be published under multiple names).
9352                if (firstClass) {
9353                    mProviderMap.putProviderByClass(comp, cpr);
9354                }
9355
9356                mProviderMap.putProviderByName(name, cpr);
9357                conn = incProviderCountLocked(r, cpr, token, stable);
9358                if (conn != null) {
9359                    conn.waiting = true;
9360                }
9361            }
9362            checkTime(startTime, "getContentProviderImpl: done!");
9363        }
9364
9365        // Wait for the provider to be published...
9366        synchronized (cpr) {
9367            while (cpr.provider == null) {
9368                if (cpr.launchingApp == null) {
9369                    Slog.w(TAG, "Unable to launch app "
9370                            + cpi.applicationInfo.packageName + "/"
9371                            + cpi.applicationInfo.uid + " for provider "
9372                            + name + ": launching app became null");
9373                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
9374                            UserHandle.getUserId(cpi.applicationInfo.uid),
9375                            cpi.applicationInfo.packageName,
9376                            cpi.applicationInfo.uid, name);
9377                    return null;
9378                }
9379                try {
9380                    if (DEBUG_MU) {
9381                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
9382                                + cpr.launchingApp);
9383                    }
9384                    if (conn != null) {
9385                        conn.waiting = true;
9386                    }
9387                    cpr.wait();
9388                } catch (InterruptedException ex) {
9389                } finally {
9390                    if (conn != null) {
9391                        conn.waiting = false;
9392                    }
9393                }
9394            }
9395        }
9396        return cpr != null ? cpr.newHolder(conn) : null;
9397    }
9398
9399    @Override
9400    public final ContentProviderHolder getContentProvider(
9401            IApplicationThread caller, String name, int userId, boolean stable) {
9402        enforceNotIsolatedCaller("getContentProvider");
9403        if (caller == null) {
9404            String msg = "null IApplicationThread when getting content provider "
9405                    + name;
9406            Slog.w(TAG, msg);
9407            throw new SecurityException(msg);
9408        }
9409        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
9410        // with cross-user grant.
9411        return getContentProviderImpl(caller, name, null, stable, userId);
9412    }
9413
9414    public ContentProviderHolder getContentProviderExternal(
9415            String name, int userId, IBinder token) {
9416        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9417            "Do not have permission in call getContentProviderExternal()");
9418        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
9419                false, ALLOW_FULL_ONLY, "getContentProvider", null);
9420        return getContentProviderExternalUnchecked(name, token, userId);
9421    }
9422
9423    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
9424            IBinder token, int userId) {
9425        return getContentProviderImpl(null, name, token, true, userId);
9426    }
9427
9428    /**
9429     * Drop a content provider from a ProcessRecord's bookkeeping
9430     */
9431    public void removeContentProvider(IBinder connection, boolean stable) {
9432        enforceNotIsolatedCaller("removeContentProvider");
9433        long ident = Binder.clearCallingIdentity();
9434        try {
9435            synchronized (this) {
9436                ContentProviderConnection conn;
9437                try {
9438                    conn = (ContentProviderConnection)connection;
9439                } catch (ClassCastException e) {
9440                    String msg ="removeContentProvider: " + connection
9441                            + " not a ContentProviderConnection";
9442                    Slog.w(TAG, msg);
9443                    throw new IllegalArgumentException(msg);
9444                }
9445                if (conn == null) {
9446                    throw new NullPointerException("connection is null");
9447                }
9448                if (decProviderCountLocked(conn, null, null, stable)) {
9449                    updateOomAdjLocked();
9450                }
9451            }
9452        } finally {
9453            Binder.restoreCallingIdentity(ident);
9454        }
9455    }
9456
9457    public void removeContentProviderExternal(String name, IBinder token) {
9458        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9459            "Do not have permission in call removeContentProviderExternal()");
9460        int userId = UserHandle.getCallingUserId();
9461        long ident = Binder.clearCallingIdentity();
9462        try {
9463            removeContentProviderExternalUnchecked(name, token, userId);
9464        } finally {
9465            Binder.restoreCallingIdentity(ident);
9466        }
9467    }
9468
9469    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
9470        synchronized (this) {
9471            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
9472            if(cpr == null) {
9473                //remove from mProvidersByClass
9474                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
9475                return;
9476            }
9477
9478            //update content provider record entry info
9479            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
9480            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
9481            if (localCpr.hasExternalProcessHandles()) {
9482                if (localCpr.removeExternalProcessHandleLocked(token)) {
9483                    updateOomAdjLocked();
9484                } else {
9485                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
9486                            + " with no external reference for token: "
9487                            + token + ".");
9488                }
9489            } else {
9490                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
9491                        + " with no external references.");
9492            }
9493        }
9494    }
9495
9496    public final void publishContentProviders(IApplicationThread caller,
9497            List<ContentProviderHolder> providers) {
9498        if (providers == null) {
9499            return;
9500        }
9501
9502        enforceNotIsolatedCaller("publishContentProviders");
9503        synchronized (this) {
9504            final ProcessRecord r = getRecordForAppLocked(caller);
9505            if (DEBUG_MU)
9506                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
9507            if (r == null) {
9508                throw new SecurityException(
9509                        "Unable to find app for caller " + caller
9510                      + " (pid=" + Binder.getCallingPid()
9511                      + ") when publishing content providers");
9512            }
9513
9514            final long origId = Binder.clearCallingIdentity();
9515
9516            final int N = providers.size();
9517            for (int i=0; i<N; i++) {
9518                ContentProviderHolder src = providers.get(i);
9519                if (src == null || src.info == null || src.provider == null) {
9520                    continue;
9521                }
9522                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
9523                if (DEBUG_MU)
9524                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
9525                if (dst != null) {
9526                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
9527                    mProviderMap.putProviderByClass(comp, dst);
9528                    String names[] = dst.info.authority.split(";");
9529                    for (int j = 0; j < names.length; j++) {
9530                        mProviderMap.putProviderByName(names[j], dst);
9531                    }
9532
9533                    int NL = mLaunchingProviders.size();
9534                    int j;
9535                    for (j=0; j<NL; j++) {
9536                        if (mLaunchingProviders.get(j) == dst) {
9537                            mLaunchingProviders.remove(j);
9538                            j--;
9539                            NL--;
9540                        }
9541                    }
9542                    synchronized (dst) {
9543                        dst.provider = src.provider;
9544                        dst.proc = r;
9545                        dst.notifyAll();
9546                    }
9547                    updateOomAdjLocked(r);
9548                }
9549            }
9550
9551            Binder.restoreCallingIdentity(origId);
9552        }
9553    }
9554
9555    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
9556        ContentProviderConnection conn;
9557        try {
9558            conn = (ContentProviderConnection)connection;
9559        } catch (ClassCastException e) {
9560            String msg ="refContentProvider: " + connection
9561                    + " not a ContentProviderConnection";
9562            Slog.w(TAG, msg);
9563            throw new IllegalArgumentException(msg);
9564        }
9565        if (conn == null) {
9566            throw new NullPointerException("connection is null");
9567        }
9568
9569        synchronized (this) {
9570            if (stable > 0) {
9571                conn.numStableIncs += stable;
9572            }
9573            stable = conn.stableCount + stable;
9574            if (stable < 0) {
9575                throw new IllegalStateException("stableCount < 0: " + stable);
9576            }
9577
9578            if (unstable > 0) {
9579                conn.numUnstableIncs += unstable;
9580            }
9581            unstable = conn.unstableCount + unstable;
9582            if (unstable < 0) {
9583                throw new IllegalStateException("unstableCount < 0: " + unstable);
9584            }
9585
9586            if ((stable+unstable) <= 0) {
9587                throw new IllegalStateException("ref counts can't go to zero here: stable="
9588                        + stable + " unstable=" + unstable);
9589            }
9590            conn.stableCount = stable;
9591            conn.unstableCount = unstable;
9592            return !conn.dead;
9593        }
9594    }
9595
9596    public void unstableProviderDied(IBinder connection) {
9597        ContentProviderConnection conn;
9598        try {
9599            conn = (ContentProviderConnection)connection;
9600        } catch (ClassCastException e) {
9601            String msg ="refContentProvider: " + connection
9602                    + " not a ContentProviderConnection";
9603            Slog.w(TAG, msg);
9604            throw new IllegalArgumentException(msg);
9605        }
9606        if (conn == null) {
9607            throw new NullPointerException("connection is null");
9608        }
9609
9610        // Safely retrieve the content provider associated with the connection.
9611        IContentProvider provider;
9612        synchronized (this) {
9613            provider = conn.provider.provider;
9614        }
9615
9616        if (provider == null) {
9617            // Um, yeah, we're way ahead of you.
9618            return;
9619        }
9620
9621        // Make sure the caller is being honest with us.
9622        if (provider.asBinder().pingBinder()) {
9623            // Er, no, still looks good to us.
9624            synchronized (this) {
9625                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
9626                        + " says " + conn + " died, but we don't agree");
9627                return;
9628            }
9629        }
9630
9631        // Well look at that!  It's dead!
9632        synchronized (this) {
9633            if (conn.provider.provider != provider) {
9634                // But something changed...  good enough.
9635                return;
9636            }
9637
9638            ProcessRecord proc = conn.provider.proc;
9639            if (proc == null || proc.thread == null) {
9640                // Seems like the process is already cleaned up.
9641                return;
9642            }
9643
9644            // As far as we're concerned, this is just like receiving a
9645            // death notification...  just a bit prematurely.
9646            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
9647                    + ") early provider death");
9648            final long ident = Binder.clearCallingIdentity();
9649            try {
9650                appDiedLocked(proc);
9651            } finally {
9652                Binder.restoreCallingIdentity(ident);
9653            }
9654        }
9655    }
9656
9657    @Override
9658    public void appNotRespondingViaProvider(IBinder connection) {
9659        enforceCallingPermission(
9660                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
9661
9662        final ContentProviderConnection conn = (ContentProviderConnection) connection;
9663        if (conn == null) {
9664            Slog.w(TAG, "ContentProviderConnection is null");
9665            return;
9666        }
9667
9668        final ProcessRecord host = conn.provider.proc;
9669        if (host == null) {
9670            Slog.w(TAG, "Failed to find hosting ProcessRecord");
9671            return;
9672        }
9673
9674        final long token = Binder.clearCallingIdentity();
9675        try {
9676            appNotResponding(host, null, null, false, "ContentProvider not responding");
9677        } finally {
9678            Binder.restoreCallingIdentity(token);
9679        }
9680    }
9681
9682    public final void installSystemProviders() {
9683        List<ProviderInfo> providers;
9684        synchronized (this) {
9685            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
9686            providers = generateApplicationProvidersLocked(app);
9687            if (providers != null) {
9688                for (int i=providers.size()-1; i>=0; i--) {
9689                    ProviderInfo pi = (ProviderInfo)providers.get(i);
9690                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
9691                        Slog.w(TAG, "Not installing system proc provider " + pi.name
9692                                + ": not system .apk");
9693                        providers.remove(i);
9694                    }
9695                }
9696            }
9697        }
9698        if (providers != null) {
9699            mSystemThread.installSystemProviders(providers);
9700        }
9701
9702        mCoreSettingsObserver = new CoreSettingsObserver(this);
9703
9704        //mUsageStatsService.monitorPackages();
9705    }
9706
9707    /**
9708     * Allows apps to retrieve the MIME type of a URI.
9709     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
9710     * users, then it does not need permission to access the ContentProvider.
9711     * Either, it needs cross-user uri grants.
9712     *
9713     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
9714     *
9715     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
9716     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
9717     */
9718    public String getProviderMimeType(Uri uri, int userId) {
9719        enforceNotIsolatedCaller("getProviderMimeType");
9720        final String name = uri.getAuthority();
9721        int callingUid = Binder.getCallingUid();
9722        int callingPid = Binder.getCallingPid();
9723        long ident = 0;
9724        boolean clearedIdentity = false;
9725        userId = unsafeConvertIncomingUser(userId);
9726        if (canClearIdentity(callingPid, callingUid, userId)) {
9727            clearedIdentity = true;
9728            ident = Binder.clearCallingIdentity();
9729        }
9730        ContentProviderHolder holder = null;
9731        try {
9732            holder = getContentProviderExternalUnchecked(name, null, userId);
9733            if (holder != null) {
9734                return holder.provider.getType(uri);
9735            }
9736        } catch (RemoteException e) {
9737            Log.w(TAG, "Content provider dead retrieving " + uri, e);
9738            return null;
9739        } finally {
9740            // We need to clear the identity to call removeContentProviderExternalUnchecked
9741            if (!clearedIdentity) {
9742                ident = Binder.clearCallingIdentity();
9743            }
9744            try {
9745                if (holder != null) {
9746                    removeContentProviderExternalUnchecked(name, null, userId);
9747                }
9748            } finally {
9749                Binder.restoreCallingIdentity(ident);
9750            }
9751        }
9752
9753        return null;
9754    }
9755
9756    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
9757        if (UserHandle.getUserId(callingUid) == userId) {
9758            return true;
9759        }
9760        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
9761                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
9762                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
9763                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
9764                return true;
9765        }
9766        return false;
9767    }
9768
9769    // =========================================================
9770    // GLOBAL MANAGEMENT
9771    // =========================================================
9772
9773    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
9774            boolean isolated, int isolatedUid) {
9775        String proc = customProcess != null ? customProcess : info.processName;
9776        BatteryStatsImpl.Uid.Proc ps = null;
9777        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9778        int uid = info.uid;
9779        if (isolated) {
9780            if (isolatedUid == 0) {
9781                int userId = UserHandle.getUserId(uid);
9782                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
9783                while (true) {
9784                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
9785                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
9786                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
9787                    }
9788                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
9789                    mNextIsolatedProcessUid++;
9790                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
9791                        // No process for this uid, use it.
9792                        break;
9793                    }
9794                    stepsLeft--;
9795                    if (stepsLeft <= 0) {
9796                        return null;
9797                    }
9798                }
9799            } else {
9800                // Special case for startIsolatedProcess (internal only), where
9801                // the uid of the isolated process is specified by the caller.
9802                uid = isolatedUid;
9803            }
9804        }
9805        return new ProcessRecord(stats, info, proc, uid);
9806    }
9807
9808    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
9809            String abiOverride) {
9810        ProcessRecord app;
9811        if (!isolated) {
9812            app = getProcessRecordLocked(info.processName, info.uid, true);
9813        } else {
9814            app = null;
9815        }
9816
9817        if (app == null) {
9818            app = newProcessRecordLocked(info, null, isolated, 0);
9819            mProcessNames.put(info.processName, app.uid, app);
9820            if (isolated) {
9821                mIsolatedProcesses.put(app.uid, app);
9822            }
9823            updateLruProcessLocked(app, false, null);
9824            updateOomAdjLocked();
9825        }
9826
9827        // This package really, really can not be stopped.
9828        try {
9829            AppGlobals.getPackageManager().setPackageStoppedState(
9830                    info.packageName, false, UserHandle.getUserId(app.uid));
9831        } catch (RemoteException e) {
9832        } catch (IllegalArgumentException e) {
9833            Slog.w(TAG, "Failed trying to unstop package "
9834                    + info.packageName + ": " + e);
9835        }
9836
9837        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
9838                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
9839            app.persistent = true;
9840            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
9841        }
9842        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
9843            mPersistentStartingProcesses.add(app);
9844            startProcessLocked(app, "added application", app.processName, abiOverride,
9845                    null /* entryPoint */, null /* entryPointArgs */);
9846        }
9847
9848        return app;
9849    }
9850
9851    public void unhandledBack() {
9852        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
9853                "unhandledBack()");
9854
9855        synchronized(this) {
9856            final long origId = Binder.clearCallingIdentity();
9857            try {
9858                getFocusedStack().unhandledBackLocked();
9859            } finally {
9860                Binder.restoreCallingIdentity(origId);
9861            }
9862        }
9863    }
9864
9865    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
9866        enforceNotIsolatedCaller("openContentUri");
9867        final int userId = UserHandle.getCallingUserId();
9868        String name = uri.getAuthority();
9869        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
9870        ParcelFileDescriptor pfd = null;
9871        if (cph != null) {
9872            // We record the binder invoker's uid in thread-local storage before
9873            // going to the content provider to open the file.  Later, in the code
9874            // that handles all permissions checks, we look for this uid and use
9875            // that rather than the Activity Manager's own uid.  The effect is that
9876            // we do the check against the caller's permissions even though it looks
9877            // to the content provider like the Activity Manager itself is making
9878            // the request.
9879            sCallerIdentity.set(new Identity(
9880                    Binder.getCallingPid(), Binder.getCallingUid()));
9881            try {
9882                pfd = cph.provider.openFile(null, uri, "r", null);
9883            } catch (FileNotFoundException e) {
9884                // do nothing; pfd will be returned null
9885            } finally {
9886                // Ensure that whatever happens, we clean up the identity state
9887                sCallerIdentity.remove();
9888            }
9889
9890            // We've got the fd now, so we're done with the provider.
9891            removeContentProviderExternalUnchecked(name, null, userId);
9892        } else {
9893            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
9894        }
9895        return pfd;
9896    }
9897
9898    // Actually is sleeping or shutting down or whatever else in the future
9899    // is an inactive state.
9900    public boolean isSleepingOrShuttingDown() {
9901        return isSleeping() || mShuttingDown;
9902    }
9903
9904    public boolean isSleeping() {
9905        return mSleeping;
9906    }
9907
9908    void goingToSleep() {
9909        synchronized(this) {
9910            mWentToSleep = true;
9911            goToSleepIfNeededLocked();
9912        }
9913    }
9914
9915    void finishRunningVoiceLocked() {
9916        if (mRunningVoice) {
9917            mRunningVoice = false;
9918            goToSleepIfNeededLocked();
9919        }
9920    }
9921
9922    void goToSleepIfNeededLocked() {
9923        if (mWentToSleep && !mRunningVoice) {
9924            if (!mSleeping) {
9925                mSleeping = true;
9926                mStackSupervisor.goingToSleepLocked();
9927
9928                // Initialize the wake times of all processes.
9929                checkExcessivePowerUsageLocked(false);
9930                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9931                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9932                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
9933            }
9934        }
9935    }
9936
9937    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
9938        if (task != null && task.stack != null && task.stack.isHomeStack()) {
9939            // Never persist the home stack.
9940            return;
9941        }
9942        mTaskPersister.wakeup(task, flush);
9943    }
9944
9945    @Override
9946    public boolean shutdown(int timeout) {
9947        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
9948                != PackageManager.PERMISSION_GRANTED) {
9949            throw new SecurityException("Requires permission "
9950                    + android.Manifest.permission.SHUTDOWN);
9951        }
9952
9953        boolean timedout = false;
9954
9955        synchronized(this) {
9956            mShuttingDown = true;
9957            updateEventDispatchingLocked();
9958            timedout = mStackSupervisor.shutdownLocked(timeout);
9959        }
9960
9961        mAppOpsService.shutdown();
9962        if (mUsageStatsService != null) {
9963            mUsageStatsService.prepareShutdown();
9964        }
9965        mBatteryStatsService.shutdown();
9966        synchronized (this) {
9967            mProcessStats.shutdownLocked();
9968        }
9969        notifyTaskPersisterLocked(null, true);
9970
9971        return timedout;
9972    }
9973
9974    public final void activitySlept(IBinder token) {
9975        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
9976
9977        final long origId = Binder.clearCallingIdentity();
9978
9979        synchronized (this) {
9980            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9981            if (r != null) {
9982                mStackSupervisor.activitySleptLocked(r);
9983            }
9984        }
9985
9986        Binder.restoreCallingIdentity(origId);
9987    }
9988
9989    private String lockScreenShownToString() {
9990        switch (mLockScreenShown) {
9991            case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
9992            case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
9993            case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
9994            default: return "Unknown=" + mLockScreenShown;
9995        }
9996    }
9997
9998    void logLockScreen(String msg) {
9999        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
10000                " mLockScreenShown=" + lockScreenShownToString() + " mWentToSleep=" +
10001                mWentToSleep + " mSleeping=" + mSleeping);
10002    }
10003
10004    void comeOutOfSleepIfNeededLocked() {
10005        if ((!mWentToSleep && mLockScreenShown == LOCK_SCREEN_HIDDEN) || mRunningVoice) {
10006            if (mSleeping) {
10007                mSleeping = false;
10008                mStackSupervisor.comeOutOfSleepIfNeededLocked();
10009            }
10010        }
10011    }
10012
10013    void wakingUp() {
10014        synchronized(this) {
10015            mWentToSleep = false;
10016            comeOutOfSleepIfNeededLocked();
10017        }
10018    }
10019
10020    void startRunningVoiceLocked() {
10021        if (!mRunningVoice) {
10022            mRunningVoice = true;
10023            comeOutOfSleepIfNeededLocked();
10024        }
10025    }
10026
10027    private void updateEventDispatchingLocked() {
10028        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
10029    }
10030
10031    public void setLockScreenShown(boolean shown) {
10032        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
10033                != PackageManager.PERMISSION_GRANTED) {
10034            throw new SecurityException("Requires permission "
10035                    + android.Manifest.permission.DEVICE_POWER);
10036        }
10037
10038        synchronized(this) {
10039            long ident = Binder.clearCallingIdentity();
10040            try {
10041                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
10042                mLockScreenShown = shown ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
10043                comeOutOfSleepIfNeededLocked();
10044            } finally {
10045                Binder.restoreCallingIdentity(ident);
10046            }
10047        }
10048    }
10049
10050    @Override
10051    public void stopAppSwitches() {
10052        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10053                != PackageManager.PERMISSION_GRANTED) {
10054            throw new SecurityException("Requires permission "
10055                    + android.Manifest.permission.STOP_APP_SWITCHES);
10056        }
10057
10058        synchronized(this) {
10059            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
10060                    + APP_SWITCH_DELAY_TIME;
10061            mDidAppSwitch = false;
10062            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10063            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10064            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
10065        }
10066    }
10067
10068    public void resumeAppSwitches() {
10069        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10070                != PackageManager.PERMISSION_GRANTED) {
10071            throw new SecurityException("Requires permission "
10072                    + android.Manifest.permission.STOP_APP_SWITCHES);
10073        }
10074
10075        synchronized(this) {
10076            // Note that we don't execute any pending app switches... we will
10077            // let those wait until either the timeout, or the next start
10078            // activity request.
10079            mAppSwitchesAllowedTime = 0;
10080        }
10081    }
10082
10083    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
10084            int callingPid, int callingUid, String name) {
10085        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
10086            return true;
10087        }
10088
10089        int perm = checkComponentPermission(
10090                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
10091                sourceUid, -1, true);
10092        if (perm == PackageManager.PERMISSION_GRANTED) {
10093            return true;
10094        }
10095
10096        // If the actual IPC caller is different from the logical source, then
10097        // also see if they are allowed to control app switches.
10098        if (callingUid != -1 && callingUid != sourceUid) {
10099            perm = checkComponentPermission(
10100                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
10101                    callingUid, -1, true);
10102            if (perm == PackageManager.PERMISSION_GRANTED) {
10103                return true;
10104            }
10105        }
10106
10107        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
10108        return false;
10109    }
10110
10111    public void setDebugApp(String packageName, boolean waitForDebugger,
10112            boolean persistent) {
10113        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
10114                "setDebugApp()");
10115
10116        long ident = Binder.clearCallingIdentity();
10117        try {
10118            // Note that this is not really thread safe if there are multiple
10119            // callers into it at the same time, but that's not a situation we
10120            // care about.
10121            if (persistent) {
10122                final ContentResolver resolver = mContext.getContentResolver();
10123                Settings.Global.putString(
10124                    resolver, Settings.Global.DEBUG_APP,
10125                    packageName);
10126                Settings.Global.putInt(
10127                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
10128                    waitForDebugger ? 1 : 0);
10129            }
10130
10131            synchronized (this) {
10132                if (!persistent) {
10133                    mOrigDebugApp = mDebugApp;
10134                    mOrigWaitForDebugger = mWaitForDebugger;
10135                }
10136                mDebugApp = packageName;
10137                mWaitForDebugger = waitForDebugger;
10138                mDebugTransient = !persistent;
10139                if (packageName != null) {
10140                    forceStopPackageLocked(packageName, -1, false, false, true, true,
10141                            false, UserHandle.USER_ALL, "set debug app");
10142                }
10143            }
10144        } finally {
10145            Binder.restoreCallingIdentity(ident);
10146        }
10147    }
10148
10149    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
10150        synchronized (this) {
10151            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10152            if (!isDebuggable) {
10153                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10154                    throw new SecurityException("Process not debuggable: " + app.packageName);
10155                }
10156            }
10157
10158            mOpenGlTraceApp = processName;
10159        }
10160    }
10161
10162    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
10163        synchronized (this) {
10164            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10165            if (!isDebuggable) {
10166                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10167                    throw new SecurityException("Process not debuggable: " + app.packageName);
10168                }
10169            }
10170            mProfileApp = processName;
10171            mProfileFile = profilerInfo.profileFile;
10172            if (mProfileFd != null) {
10173                try {
10174                    mProfileFd.close();
10175                } catch (IOException e) {
10176                }
10177                mProfileFd = null;
10178            }
10179            mProfileFd = profilerInfo.profileFd;
10180            mSamplingInterval = profilerInfo.samplingInterval;
10181            mAutoStopProfiler = profilerInfo.autoStopProfiler;
10182            mProfileType = 0;
10183        }
10184    }
10185
10186    @Override
10187    public void setAlwaysFinish(boolean enabled) {
10188        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
10189                "setAlwaysFinish()");
10190
10191        Settings.Global.putInt(
10192                mContext.getContentResolver(),
10193                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
10194
10195        synchronized (this) {
10196            mAlwaysFinishActivities = enabled;
10197        }
10198    }
10199
10200    @Override
10201    public void setActivityController(IActivityController controller) {
10202        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10203                "setActivityController()");
10204        synchronized (this) {
10205            mController = controller;
10206            Watchdog.getInstance().setActivityController(controller);
10207        }
10208    }
10209
10210    @Override
10211    public void setUserIsMonkey(boolean userIsMonkey) {
10212        synchronized (this) {
10213            synchronized (mPidsSelfLocked) {
10214                final int callingPid = Binder.getCallingPid();
10215                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
10216                if (precessRecord == null) {
10217                    throw new SecurityException("Unknown process: " + callingPid);
10218                }
10219                if (precessRecord.instrumentationUiAutomationConnection  == null) {
10220                    throw new SecurityException("Only an instrumentation process "
10221                            + "with a UiAutomation can call setUserIsMonkey");
10222                }
10223            }
10224            mUserIsMonkey = userIsMonkey;
10225        }
10226    }
10227
10228    @Override
10229    public boolean isUserAMonkey() {
10230        synchronized (this) {
10231            // If there is a controller also implies the user is a monkey.
10232            return (mUserIsMonkey || mController != null);
10233        }
10234    }
10235
10236    public void requestBugReport() {
10237        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
10238        SystemProperties.set("ctl.start", "bugreport");
10239    }
10240
10241    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
10242        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
10243    }
10244
10245    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
10246        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
10247            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
10248        }
10249        return KEY_DISPATCHING_TIMEOUT;
10250    }
10251
10252    @Override
10253    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
10254        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10255                != PackageManager.PERMISSION_GRANTED) {
10256            throw new SecurityException("Requires permission "
10257                    + android.Manifest.permission.FILTER_EVENTS);
10258        }
10259        ProcessRecord proc;
10260        long timeout;
10261        synchronized (this) {
10262            synchronized (mPidsSelfLocked) {
10263                proc = mPidsSelfLocked.get(pid);
10264            }
10265            timeout = getInputDispatchingTimeoutLocked(proc);
10266        }
10267
10268        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
10269            return -1;
10270        }
10271
10272        return timeout;
10273    }
10274
10275    /**
10276     * Handle input dispatching timeouts.
10277     * Returns whether input dispatching should be aborted or not.
10278     */
10279    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
10280            final ActivityRecord activity, final ActivityRecord parent,
10281            final boolean aboveSystem, String reason) {
10282        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10283                != PackageManager.PERMISSION_GRANTED) {
10284            throw new SecurityException("Requires permission "
10285                    + android.Manifest.permission.FILTER_EVENTS);
10286        }
10287
10288        final String annotation;
10289        if (reason == null) {
10290            annotation = "Input dispatching timed out";
10291        } else {
10292            annotation = "Input dispatching timed out (" + reason + ")";
10293        }
10294
10295        if (proc != null) {
10296            synchronized (this) {
10297                if (proc.debugging) {
10298                    return false;
10299                }
10300
10301                if (mDidDexOpt) {
10302                    // Give more time since we were dexopting.
10303                    mDidDexOpt = false;
10304                    return false;
10305                }
10306
10307                if (proc.instrumentationClass != null) {
10308                    Bundle info = new Bundle();
10309                    info.putString("shortMsg", "keyDispatchingTimedOut");
10310                    info.putString("longMsg", annotation);
10311                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
10312                    return true;
10313                }
10314            }
10315            mHandler.post(new Runnable() {
10316                @Override
10317                public void run() {
10318                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
10319                }
10320            });
10321        }
10322
10323        return true;
10324    }
10325
10326    public Bundle getAssistContextExtras(int requestType) {
10327        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null,
10328                UserHandle.getCallingUserId());
10329        if (pae == null) {
10330            return null;
10331        }
10332        synchronized (pae) {
10333            while (!pae.haveResult) {
10334                try {
10335                    pae.wait();
10336                } catch (InterruptedException e) {
10337                }
10338            }
10339            if (pae.result != null) {
10340                pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
10341            }
10342        }
10343        synchronized (this) {
10344            mPendingAssistExtras.remove(pae);
10345            mHandler.removeCallbacks(pae);
10346        }
10347        return pae.extras;
10348    }
10349
10350    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
10351            int userHandle) {
10352        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
10353                "getAssistContextExtras()");
10354        PendingAssistExtras pae;
10355        Bundle extras = new Bundle();
10356        synchronized (this) {
10357            ActivityRecord activity = getFocusedStack().mResumedActivity;
10358            if (activity == null) {
10359                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
10360                return null;
10361            }
10362            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
10363            if (activity.app == null || activity.app.thread == null) {
10364                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
10365                return null;
10366            }
10367            if (activity.app.pid == Binder.getCallingPid()) {
10368                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
10369                return null;
10370            }
10371            pae = new PendingAssistExtras(activity, extras, intent, hint, userHandle);
10372            try {
10373                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
10374                        requestType);
10375                mPendingAssistExtras.add(pae);
10376                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
10377            } catch (RemoteException e) {
10378                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
10379                return null;
10380            }
10381            return pae;
10382        }
10383    }
10384
10385    public void reportAssistContextExtras(IBinder token, Bundle extras) {
10386        PendingAssistExtras pae = (PendingAssistExtras)token;
10387        synchronized (pae) {
10388            pae.result = extras;
10389            pae.haveResult = true;
10390            pae.notifyAll();
10391            if (pae.intent == null) {
10392                // Caller is just waiting for the result.
10393                return;
10394            }
10395        }
10396
10397        // We are now ready to launch the assist activity.
10398        synchronized (this) {
10399            boolean exists = mPendingAssistExtras.remove(pae);
10400            mHandler.removeCallbacks(pae);
10401            if (!exists) {
10402                // Timed out.
10403                return;
10404            }
10405        }
10406        pae.intent.replaceExtras(extras);
10407        if (pae.hint != null) {
10408            pae.intent.putExtra(pae.hint, true);
10409        }
10410        pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10411                | Intent.FLAG_ACTIVITY_SINGLE_TOP
10412                | Intent.FLAG_ACTIVITY_CLEAR_TOP);
10413        closeSystemDialogs("assist");
10414        try {
10415            mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
10416        } catch (ActivityNotFoundException e) {
10417            Slog.w(TAG, "No activity to handle assist action.", e);
10418        }
10419    }
10420
10421    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle) {
10422        return enqueueAssistContext(requestType, intent, hint, userHandle) != null;
10423    }
10424
10425    public void registerProcessObserver(IProcessObserver observer) {
10426        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10427                "registerProcessObserver()");
10428        synchronized (this) {
10429            mProcessObservers.register(observer);
10430        }
10431    }
10432
10433    @Override
10434    public void unregisterProcessObserver(IProcessObserver observer) {
10435        synchronized (this) {
10436            mProcessObservers.unregister(observer);
10437        }
10438    }
10439
10440    @Override
10441    public boolean convertFromTranslucent(IBinder token) {
10442        final long origId = Binder.clearCallingIdentity();
10443        try {
10444            synchronized (this) {
10445                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10446                if (r == null) {
10447                    return false;
10448                }
10449                final boolean translucentChanged = r.changeWindowTranslucency(true);
10450                if (translucentChanged) {
10451                    r.task.stack.releaseBackgroundResources();
10452                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10453                }
10454                mWindowManager.setAppFullscreen(token, true);
10455                return translucentChanged;
10456            }
10457        } finally {
10458            Binder.restoreCallingIdentity(origId);
10459        }
10460    }
10461
10462    @Override
10463    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
10464        final long origId = Binder.clearCallingIdentity();
10465        try {
10466            synchronized (this) {
10467                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10468                if (r == null) {
10469                    return false;
10470                }
10471                int index = r.task.mActivities.lastIndexOf(r);
10472                if (index > 0) {
10473                    ActivityRecord under = r.task.mActivities.get(index - 1);
10474                    under.returningOptions = options;
10475                }
10476                final boolean translucentChanged = r.changeWindowTranslucency(false);
10477                if (translucentChanged) {
10478                    r.task.stack.convertToTranslucent(r);
10479                }
10480                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10481                mWindowManager.setAppFullscreen(token, false);
10482                return translucentChanged;
10483            }
10484        } finally {
10485            Binder.restoreCallingIdentity(origId);
10486        }
10487    }
10488
10489    @Override
10490    public boolean requestVisibleBehind(IBinder token, boolean visible) {
10491        final long origId = Binder.clearCallingIdentity();
10492        try {
10493            synchronized (this) {
10494                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10495                if (r != null) {
10496                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
10497                }
10498            }
10499            return false;
10500        } finally {
10501            Binder.restoreCallingIdentity(origId);
10502        }
10503    }
10504
10505    @Override
10506    public boolean isBackgroundVisibleBehind(IBinder token) {
10507        final long origId = Binder.clearCallingIdentity();
10508        try {
10509            synchronized (this) {
10510                final ActivityStack stack = ActivityRecord.getStackLocked(token);
10511                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
10512                if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG,
10513                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
10514                return visible;
10515            }
10516        } finally {
10517            Binder.restoreCallingIdentity(origId);
10518        }
10519    }
10520
10521    @Override
10522    public ActivityOptions getActivityOptions(IBinder token) {
10523        final long origId = Binder.clearCallingIdentity();
10524        try {
10525            synchronized (this) {
10526                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10527                if (r != null) {
10528                    final ActivityOptions activityOptions = r.pendingOptions;
10529                    r.pendingOptions = null;
10530                    return activityOptions;
10531                }
10532                return null;
10533            }
10534        } finally {
10535            Binder.restoreCallingIdentity(origId);
10536        }
10537    }
10538
10539    @Override
10540    public void setImmersive(IBinder token, boolean immersive) {
10541        synchronized(this) {
10542            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10543            if (r == null) {
10544                throw new IllegalArgumentException();
10545            }
10546            r.immersive = immersive;
10547
10548            // update associated state if we're frontmost
10549            if (r == mFocusedActivity) {
10550                if (DEBUG_IMMERSIVE) {
10551                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
10552                }
10553                applyUpdateLockStateLocked(r);
10554            }
10555        }
10556    }
10557
10558    @Override
10559    public boolean isImmersive(IBinder token) {
10560        synchronized (this) {
10561            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10562            if (r == null) {
10563                throw new IllegalArgumentException();
10564            }
10565            return r.immersive;
10566        }
10567    }
10568
10569    public boolean isTopActivityImmersive() {
10570        enforceNotIsolatedCaller("startActivity");
10571        synchronized (this) {
10572            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
10573            return (r != null) ? r.immersive : false;
10574        }
10575    }
10576
10577    @Override
10578    public boolean isTopOfTask(IBinder token) {
10579        synchronized (this) {
10580            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10581            if (r == null) {
10582                throw new IllegalArgumentException();
10583            }
10584            return r.task.getTopActivity() == r;
10585        }
10586    }
10587
10588    public final void enterSafeMode() {
10589        synchronized(this) {
10590            // It only makes sense to do this before the system is ready
10591            // and started launching other packages.
10592            if (!mSystemReady) {
10593                try {
10594                    AppGlobals.getPackageManager().enterSafeMode();
10595                } catch (RemoteException e) {
10596                }
10597            }
10598
10599            mSafeMode = true;
10600        }
10601    }
10602
10603    public final void showSafeModeOverlay() {
10604        View v = LayoutInflater.from(mContext).inflate(
10605                com.android.internal.R.layout.safe_mode, null);
10606        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
10607        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
10608        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
10609        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
10610        lp.gravity = Gravity.BOTTOM | Gravity.START;
10611        lp.format = v.getBackground().getOpacity();
10612        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
10613                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
10614        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
10615        ((WindowManager)mContext.getSystemService(
10616                Context.WINDOW_SERVICE)).addView(v, lp);
10617    }
10618
10619    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
10620        if (!(sender instanceof PendingIntentRecord)) {
10621            return;
10622        }
10623        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10624        synchronized (stats) {
10625            if (mBatteryStatsService.isOnBattery()) {
10626                mBatteryStatsService.enforceCallingPermission();
10627                PendingIntentRecord rec = (PendingIntentRecord)sender;
10628                int MY_UID = Binder.getCallingUid();
10629                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
10630                BatteryStatsImpl.Uid.Pkg pkg =
10631                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
10632                            sourcePkg != null ? sourcePkg : rec.key.packageName);
10633                pkg.incWakeupsLocked();
10634            }
10635        }
10636    }
10637
10638    public boolean killPids(int[] pids, String pReason, boolean secure) {
10639        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10640            throw new SecurityException("killPids only available to the system");
10641        }
10642        String reason = (pReason == null) ? "Unknown" : pReason;
10643        // XXX Note: don't acquire main activity lock here, because the window
10644        // manager calls in with its locks held.
10645
10646        boolean killed = false;
10647        synchronized (mPidsSelfLocked) {
10648            int[] types = new int[pids.length];
10649            int worstType = 0;
10650            for (int i=0; i<pids.length; i++) {
10651                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10652                if (proc != null) {
10653                    int type = proc.setAdj;
10654                    types[i] = type;
10655                    if (type > worstType) {
10656                        worstType = type;
10657                    }
10658                }
10659            }
10660
10661            // If the worst oom_adj is somewhere in the cached proc LRU range,
10662            // then constrain it so we will kill all cached procs.
10663            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
10664                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
10665                worstType = ProcessList.CACHED_APP_MIN_ADJ;
10666            }
10667
10668            // If this is not a secure call, don't let it kill processes that
10669            // are important.
10670            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
10671                worstType = ProcessList.SERVICE_ADJ;
10672            }
10673
10674            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
10675            for (int i=0; i<pids.length; i++) {
10676                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10677                if (proc == null) {
10678                    continue;
10679                }
10680                int adj = proc.setAdj;
10681                if (adj >= worstType && !proc.killedByAm) {
10682                    proc.kill(reason, true);
10683                    killed = true;
10684                }
10685            }
10686        }
10687        return killed;
10688    }
10689
10690    @Override
10691    public void killUid(int uid, String reason) {
10692        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10693            throw new SecurityException("killUid only available to the system");
10694        }
10695        synchronized (this) {
10696            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
10697                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
10698                    reason != null ? reason : "kill uid");
10699        }
10700    }
10701
10702    @Override
10703    public boolean killProcessesBelowForeground(String reason) {
10704        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10705            throw new SecurityException("killProcessesBelowForeground() only available to system");
10706        }
10707
10708        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
10709    }
10710
10711    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
10712        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10713            throw new SecurityException("killProcessesBelowAdj() only available to system");
10714        }
10715
10716        boolean killed = false;
10717        synchronized (mPidsSelfLocked) {
10718            final int size = mPidsSelfLocked.size();
10719            for (int i = 0; i < size; i++) {
10720                final int pid = mPidsSelfLocked.keyAt(i);
10721                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10722                if (proc == null) continue;
10723
10724                final int adj = proc.setAdj;
10725                if (adj > belowAdj && !proc.killedByAm) {
10726                    proc.kill(reason, true);
10727                    killed = true;
10728                }
10729            }
10730        }
10731        return killed;
10732    }
10733
10734    @Override
10735    public void hang(final IBinder who, boolean allowRestart) {
10736        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10737                != PackageManager.PERMISSION_GRANTED) {
10738            throw new SecurityException("Requires permission "
10739                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10740        }
10741
10742        final IBinder.DeathRecipient death = new DeathRecipient() {
10743            @Override
10744            public void binderDied() {
10745                synchronized (this) {
10746                    notifyAll();
10747                }
10748            }
10749        };
10750
10751        try {
10752            who.linkToDeath(death, 0);
10753        } catch (RemoteException e) {
10754            Slog.w(TAG, "hang: given caller IBinder is already dead.");
10755            return;
10756        }
10757
10758        synchronized (this) {
10759            Watchdog.getInstance().setAllowRestart(allowRestart);
10760            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
10761            synchronized (death) {
10762                while (who.isBinderAlive()) {
10763                    try {
10764                        death.wait();
10765                    } catch (InterruptedException e) {
10766                    }
10767                }
10768            }
10769            Watchdog.getInstance().setAllowRestart(true);
10770        }
10771    }
10772
10773    @Override
10774    public void restart() {
10775        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10776                != PackageManager.PERMISSION_GRANTED) {
10777            throw new SecurityException("Requires permission "
10778                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10779        }
10780
10781        Log.i(TAG, "Sending shutdown broadcast...");
10782
10783        BroadcastReceiver br = new BroadcastReceiver() {
10784            @Override public void onReceive(Context context, Intent intent) {
10785                // Now the broadcast is done, finish up the low-level shutdown.
10786                Log.i(TAG, "Shutting down activity manager...");
10787                shutdown(10000);
10788                Log.i(TAG, "Shutdown complete, restarting!");
10789                Process.killProcess(Process.myPid());
10790                System.exit(10);
10791            }
10792        };
10793
10794        // First send the high-level shut down broadcast.
10795        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
10796        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
10797        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
10798        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
10799        mContext.sendOrderedBroadcastAsUser(intent,
10800                UserHandle.ALL, null, br, mHandler, 0, null, null);
10801        */
10802        br.onReceive(mContext, intent);
10803    }
10804
10805    private long getLowRamTimeSinceIdle(long now) {
10806        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
10807    }
10808
10809    @Override
10810    public void performIdleMaintenance() {
10811        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10812                != PackageManager.PERMISSION_GRANTED) {
10813            throw new SecurityException("Requires permission "
10814                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10815        }
10816
10817        synchronized (this) {
10818            final long now = SystemClock.uptimeMillis();
10819            final long timeSinceLastIdle = now - mLastIdleTime;
10820            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
10821            mLastIdleTime = now;
10822            mLowRamTimeSinceLastIdle = 0;
10823            if (mLowRamStartTime != 0) {
10824                mLowRamStartTime = now;
10825            }
10826
10827            StringBuilder sb = new StringBuilder(128);
10828            sb.append("Idle maintenance over ");
10829            TimeUtils.formatDuration(timeSinceLastIdle, sb);
10830            sb.append(" low RAM for ");
10831            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
10832            Slog.i(TAG, sb.toString());
10833
10834            // If at least 1/3 of our time since the last idle period has been spent
10835            // with RAM low, then we want to kill processes.
10836            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
10837
10838            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
10839                ProcessRecord proc = mLruProcesses.get(i);
10840                if (proc.notCachedSinceIdle) {
10841                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
10842                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
10843                        if (doKilling && proc.initialIdlePss != 0
10844                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
10845                            proc.kill("idle maint (pss " + proc.lastPss
10846                                    + " from " + proc.initialIdlePss + ")", true);
10847                        }
10848                    }
10849                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
10850                    proc.notCachedSinceIdle = true;
10851                    proc.initialIdlePss = 0;
10852                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
10853                            isSleeping(), now);
10854                }
10855            }
10856
10857            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
10858            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
10859        }
10860    }
10861
10862    private void retrieveSettings() {
10863        final ContentResolver resolver = mContext.getContentResolver();
10864        String debugApp = Settings.Global.getString(
10865            resolver, Settings.Global.DEBUG_APP);
10866        boolean waitForDebugger = Settings.Global.getInt(
10867            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
10868        boolean alwaysFinishActivities = Settings.Global.getInt(
10869            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
10870        boolean forceRtl = Settings.Global.getInt(
10871                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
10872        // Transfer any global setting for forcing RTL layout, into a System Property
10873        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
10874
10875        Configuration configuration = new Configuration();
10876        Settings.System.getConfiguration(resolver, configuration);
10877        if (forceRtl) {
10878            // This will take care of setting the correct layout direction flags
10879            configuration.setLayoutDirection(configuration.locale);
10880        }
10881
10882        synchronized (this) {
10883            mDebugApp = mOrigDebugApp = debugApp;
10884            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
10885            mAlwaysFinishActivities = alwaysFinishActivities;
10886            // This happens before any activities are started, so we can
10887            // change mConfiguration in-place.
10888            updateConfigurationLocked(configuration, null, false, true);
10889            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
10890        }
10891    }
10892
10893    /** Loads resources after the current configuration has been set. */
10894    private void loadResourcesOnSystemReady() {
10895        final Resources res = mContext.getResources();
10896        mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
10897        mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
10898        mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
10899    }
10900
10901    public boolean testIsSystemReady() {
10902        // no need to synchronize(this) just to read & return the value
10903        return mSystemReady;
10904    }
10905
10906    private static File getCalledPreBootReceiversFile() {
10907        File dataDir = Environment.getDataDirectory();
10908        File systemDir = new File(dataDir, "system");
10909        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
10910        return fname;
10911    }
10912
10913    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
10914        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
10915        File file = getCalledPreBootReceiversFile();
10916        FileInputStream fis = null;
10917        try {
10918            fis = new FileInputStream(file);
10919            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
10920            int fvers = dis.readInt();
10921            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
10922                String vers = dis.readUTF();
10923                String codename = dis.readUTF();
10924                String build = dis.readUTF();
10925                if (android.os.Build.VERSION.RELEASE.equals(vers)
10926                        && android.os.Build.VERSION.CODENAME.equals(codename)
10927                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
10928                    int num = dis.readInt();
10929                    while (num > 0) {
10930                        num--;
10931                        String pkg = dis.readUTF();
10932                        String cls = dis.readUTF();
10933                        lastDoneReceivers.add(new ComponentName(pkg, cls));
10934                    }
10935                }
10936            }
10937        } catch (FileNotFoundException e) {
10938        } catch (IOException e) {
10939            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
10940        } finally {
10941            if (fis != null) {
10942                try {
10943                    fis.close();
10944                } catch (IOException e) {
10945                }
10946            }
10947        }
10948        return lastDoneReceivers;
10949    }
10950
10951    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
10952        File file = getCalledPreBootReceiversFile();
10953        FileOutputStream fos = null;
10954        DataOutputStream dos = null;
10955        try {
10956            fos = new FileOutputStream(file);
10957            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
10958            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
10959            dos.writeUTF(android.os.Build.VERSION.RELEASE);
10960            dos.writeUTF(android.os.Build.VERSION.CODENAME);
10961            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
10962            dos.writeInt(list.size());
10963            for (int i=0; i<list.size(); i++) {
10964                dos.writeUTF(list.get(i).getPackageName());
10965                dos.writeUTF(list.get(i).getClassName());
10966            }
10967        } catch (IOException e) {
10968            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
10969            file.delete();
10970        } finally {
10971            FileUtils.sync(fos);
10972            if (dos != null) {
10973                try {
10974                    dos.close();
10975                } catch (IOException e) {
10976                    // TODO Auto-generated catch block
10977                    e.printStackTrace();
10978                }
10979            }
10980        }
10981    }
10982
10983    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
10984            ArrayList<ComponentName> doneReceivers, int userId) {
10985        boolean waitingUpdate = false;
10986        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
10987        List<ResolveInfo> ris = null;
10988        try {
10989            ris = AppGlobals.getPackageManager().queryIntentReceivers(
10990                    intent, null, 0, userId);
10991        } catch (RemoteException e) {
10992        }
10993        if (ris != null) {
10994            for (int i=ris.size()-1; i>=0; i--) {
10995                if ((ris.get(i).activityInfo.applicationInfo.flags
10996                        &ApplicationInfo.FLAG_SYSTEM) == 0) {
10997                    ris.remove(i);
10998                }
10999            }
11000            intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
11001
11002            // For User 0, load the version number. When delivering to a new user, deliver
11003            // to all receivers.
11004            if (userId == UserHandle.USER_OWNER) {
11005                ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
11006                for (int i=0; i<ris.size(); i++) {
11007                    ActivityInfo ai = ris.get(i).activityInfo;
11008                    ComponentName comp = new ComponentName(ai.packageName, ai.name);
11009                    if (lastDoneReceivers.contains(comp)) {
11010                        // We already did the pre boot receiver for this app with the current
11011                        // platform version, so don't do it again...
11012                        ris.remove(i);
11013                        i--;
11014                        // ...however, do keep it as one that has been done, so we don't
11015                        // forget about it when rewriting the file of last done receivers.
11016                        doneReceivers.add(comp);
11017                    }
11018                }
11019            }
11020
11021            // If primary user, send broadcast to all available users, else just to userId
11022            final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
11023                    : new int[] { userId };
11024            for (int i = 0; i < ris.size(); i++) {
11025                ActivityInfo ai = ris.get(i).activityInfo;
11026                ComponentName comp = new ComponentName(ai.packageName, ai.name);
11027                doneReceivers.add(comp);
11028                intent.setComponent(comp);
11029                for (int j=0; j<users.length; j++) {
11030                    IIntentReceiver finisher = null;
11031                    // On last receiver and user, set up a completion callback
11032                    if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) {
11033                        finisher = new IIntentReceiver.Stub() {
11034                            public void performReceive(Intent intent, int resultCode,
11035                                    String data, Bundle extras, boolean ordered,
11036                                    boolean sticky, int sendingUser) {
11037                                // The raw IIntentReceiver interface is called
11038                                // with the AM lock held, so redispatch to
11039                                // execute our code without the lock.
11040                                mHandler.post(onFinishCallback);
11041                            }
11042                        };
11043                    }
11044                    Slog.i(TAG, "Sending system update to " + intent.getComponent()
11045                            + " for user " + users[j]);
11046                    broadcastIntentLocked(null, null, intent, null, finisher,
11047                            0, null, null, null, AppOpsManager.OP_NONE,
11048                            true, false, MY_PID, Process.SYSTEM_UID,
11049                            users[j]);
11050                    if (finisher != null) {
11051                        waitingUpdate = true;
11052                    }
11053                }
11054            }
11055        }
11056
11057        return waitingUpdate;
11058    }
11059
11060    public void systemReady(final Runnable goingCallback) {
11061        synchronized(this) {
11062            if (mSystemReady) {
11063                // If we're done calling all the receivers, run the next "boot phase" passed in
11064                // by the SystemServer
11065                if (goingCallback != null) {
11066                    goingCallback.run();
11067                }
11068                return;
11069            }
11070
11071            // Make sure we have the current profile info, since it is needed for
11072            // security checks.
11073            updateCurrentProfileIdsLocked();
11074
11075            if (mRecentTasks == null) {
11076                mRecentTasks = mTaskPersister.restoreTasksLocked();
11077                if (!mRecentTasks.isEmpty()) {
11078                    mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks);
11079                }
11080                cleanupRecentTasksLocked(UserHandle.USER_ALL);
11081                mTaskPersister.startPersisting();
11082            }
11083
11084            // Check to see if there are any update receivers to run.
11085            if (!mDidUpdate) {
11086                if (mWaitingUpdate) {
11087                    return;
11088                }
11089                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
11090                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
11091                    public void run() {
11092                        synchronized (ActivityManagerService.this) {
11093                            mDidUpdate = true;
11094                        }
11095                        writeLastDonePreBootReceivers(doneReceivers);
11096                        showBootMessage(mContext.getText(
11097                                R.string.android_upgrading_complete),
11098                                false);
11099                        systemReady(goingCallback);
11100                    }
11101                }, doneReceivers, UserHandle.USER_OWNER);
11102
11103                if (mWaitingUpdate) {
11104                    return;
11105                }
11106                mDidUpdate = true;
11107            }
11108
11109            mAppOpsService.systemReady();
11110            mSystemReady = true;
11111        }
11112
11113        ArrayList<ProcessRecord> procsToKill = null;
11114        synchronized(mPidsSelfLocked) {
11115            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
11116                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
11117                if (!isAllowedWhileBooting(proc.info)){
11118                    if (procsToKill == null) {
11119                        procsToKill = new ArrayList<ProcessRecord>();
11120                    }
11121                    procsToKill.add(proc);
11122                }
11123            }
11124        }
11125
11126        synchronized(this) {
11127            if (procsToKill != null) {
11128                for (int i=procsToKill.size()-1; i>=0; i--) {
11129                    ProcessRecord proc = procsToKill.get(i);
11130                    Slog.i(TAG, "Removing system update proc: " + proc);
11131                    removeProcessLocked(proc, true, false, "system update done");
11132                }
11133            }
11134
11135            // Now that we have cleaned up any update processes, we
11136            // are ready to start launching real processes and know that
11137            // we won't trample on them any more.
11138            mProcessesReady = true;
11139        }
11140
11141        Slog.i(TAG, "System now ready");
11142        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
11143            SystemClock.uptimeMillis());
11144
11145        synchronized(this) {
11146            // Make sure we have no pre-ready processes sitting around.
11147
11148            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11149                ResolveInfo ri = mContext.getPackageManager()
11150                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
11151                                STOCK_PM_FLAGS);
11152                CharSequence errorMsg = null;
11153                if (ri != null) {
11154                    ActivityInfo ai = ri.activityInfo;
11155                    ApplicationInfo app = ai.applicationInfo;
11156                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
11157                        mTopAction = Intent.ACTION_FACTORY_TEST;
11158                        mTopData = null;
11159                        mTopComponent = new ComponentName(app.packageName,
11160                                ai.name);
11161                    } else {
11162                        errorMsg = mContext.getResources().getText(
11163                                com.android.internal.R.string.factorytest_not_system);
11164                    }
11165                } else {
11166                    errorMsg = mContext.getResources().getText(
11167                            com.android.internal.R.string.factorytest_no_action);
11168                }
11169                if (errorMsg != null) {
11170                    mTopAction = null;
11171                    mTopData = null;
11172                    mTopComponent = null;
11173                    Message msg = Message.obtain();
11174                    msg.what = SHOW_FACTORY_ERROR_MSG;
11175                    msg.getData().putCharSequence("msg", errorMsg);
11176                    mHandler.sendMessage(msg);
11177                }
11178            }
11179        }
11180
11181        retrieveSettings();
11182        loadResourcesOnSystemReady();
11183
11184        synchronized (this) {
11185            readGrantedUriPermissionsLocked();
11186        }
11187
11188        if (goingCallback != null) goingCallback.run();
11189
11190        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
11191                Integer.toString(mCurrentUserId), mCurrentUserId);
11192        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
11193                Integer.toString(mCurrentUserId), mCurrentUserId);
11194        mSystemServiceManager.startUser(mCurrentUserId);
11195
11196        synchronized (this) {
11197            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11198                try {
11199                    List apps = AppGlobals.getPackageManager().
11200                        getPersistentApplications(STOCK_PM_FLAGS);
11201                    if (apps != null) {
11202                        int N = apps.size();
11203                        int i;
11204                        for (i=0; i<N; i++) {
11205                            ApplicationInfo info
11206                                = (ApplicationInfo)apps.get(i);
11207                            if (info != null &&
11208                                    !info.packageName.equals("android")) {
11209                                addAppLocked(info, false, null /* ABI override */);
11210                            }
11211                        }
11212                    }
11213                } catch (RemoteException ex) {
11214                    // pm is in same process, this will never happen.
11215                }
11216            }
11217
11218            // Start up initial activity.
11219            mBooting = true;
11220            startHomeActivityLocked(mCurrentUserId);
11221
11222            try {
11223                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
11224                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
11225                            + " data partition or your device will be unstable.");
11226                    mHandler.obtainMessage(SHOW_UID_ERROR_MSG).sendToTarget();
11227                }
11228            } catch (RemoteException e) {
11229            }
11230
11231            if (!Build.isFingerprintConsistent()) {
11232                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
11233                mHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_MSG).sendToTarget();
11234            }
11235
11236            long ident = Binder.clearCallingIdentity();
11237            try {
11238                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
11239                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
11240                        | Intent.FLAG_RECEIVER_FOREGROUND);
11241                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11242                broadcastIntentLocked(null, null, intent,
11243                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
11244                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
11245                intent = new Intent(Intent.ACTION_USER_STARTING);
11246                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11247                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11248                broadcastIntentLocked(null, null, intent,
11249                        null, new IIntentReceiver.Stub() {
11250                            @Override
11251                            public void performReceive(Intent intent, int resultCode, String data,
11252                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
11253                                    throws RemoteException {
11254                            }
11255                        }, 0, null, null,
11256                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
11257                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
11258            } catch (Throwable t) {
11259                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
11260            } finally {
11261                Binder.restoreCallingIdentity(ident);
11262            }
11263            mStackSupervisor.resumeTopActivitiesLocked();
11264            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
11265        }
11266    }
11267
11268    private boolean makeAppCrashingLocked(ProcessRecord app,
11269            String shortMsg, String longMsg, String stackTrace) {
11270        app.crashing = true;
11271        app.crashingReport = generateProcessError(app,
11272                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
11273        startAppProblemLocked(app);
11274        app.stopFreezingAllLocked();
11275        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
11276    }
11277
11278    private void makeAppNotRespondingLocked(ProcessRecord app,
11279            String activity, String shortMsg, String longMsg) {
11280        app.notResponding = true;
11281        app.notRespondingReport = generateProcessError(app,
11282                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
11283                activity, shortMsg, longMsg, null);
11284        startAppProblemLocked(app);
11285        app.stopFreezingAllLocked();
11286    }
11287
11288    /**
11289     * Generate a process error record, suitable for attachment to a ProcessRecord.
11290     *
11291     * @param app The ProcessRecord in which the error occurred.
11292     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
11293     *                      ActivityManager.AppErrorStateInfo
11294     * @param activity The activity associated with the crash, if known.
11295     * @param shortMsg Short message describing the crash.
11296     * @param longMsg Long message describing the crash.
11297     * @param stackTrace Full crash stack trace, may be null.
11298     *
11299     * @return Returns a fully-formed AppErrorStateInfo record.
11300     */
11301    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
11302            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
11303        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
11304
11305        report.condition = condition;
11306        report.processName = app.processName;
11307        report.pid = app.pid;
11308        report.uid = app.info.uid;
11309        report.tag = activity;
11310        report.shortMsg = shortMsg;
11311        report.longMsg = longMsg;
11312        report.stackTrace = stackTrace;
11313
11314        return report;
11315    }
11316
11317    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
11318        synchronized (this) {
11319            app.crashing = false;
11320            app.crashingReport = null;
11321            app.notResponding = false;
11322            app.notRespondingReport = null;
11323            if (app.anrDialog == fromDialog) {
11324                app.anrDialog = null;
11325            }
11326            if (app.waitDialog == fromDialog) {
11327                app.waitDialog = null;
11328            }
11329            if (app.pid > 0 && app.pid != MY_PID) {
11330                handleAppCrashLocked(app, null, null, null);
11331                app.kill("user request after error", true);
11332            }
11333        }
11334    }
11335
11336    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
11337            String stackTrace) {
11338        long now = SystemClock.uptimeMillis();
11339
11340        Long crashTime;
11341        if (!app.isolated) {
11342            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
11343        } else {
11344            crashTime = null;
11345        }
11346        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
11347            // This process loses!
11348            Slog.w(TAG, "Process " + app.info.processName
11349                    + " has crashed too many times: killing!");
11350            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
11351                    app.userId, app.info.processName, app.uid);
11352            mStackSupervisor.handleAppCrashLocked(app);
11353            if (!app.persistent) {
11354                // We don't want to start this process again until the user
11355                // explicitly does so...  but for persistent process, we really
11356                // need to keep it running.  If a persistent process is actually
11357                // repeatedly crashing, then badness for everyone.
11358                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
11359                        app.info.processName);
11360                if (!app.isolated) {
11361                    // XXX We don't have a way to mark isolated processes
11362                    // as bad, since they don't have a peristent identity.
11363                    mBadProcesses.put(app.info.processName, app.uid,
11364                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
11365                    mProcessCrashTimes.remove(app.info.processName, app.uid);
11366                }
11367                app.bad = true;
11368                app.removed = true;
11369                // Don't let services in this process be restarted and potentially
11370                // annoy the user repeatedly.  Unless it is persistent, since those
11371                // processes run critical code.
11372                removeProcessLocked(app, false, false, "crash");
11373                mStackSupervisor.resumeTopActivitiesLocked();
11374                return false;
11375            }
11376            mStackSupervisor.resumeTopActivitiesLocked();
11377        } else {
11378            mStackSupervisor.finishTopRunningActivityLocked(app);
11379        }
11380
11381        // Bump up the crash count of any services currently running in the proc.
11382        for (int i=app.services.size()-1; i>=0; i--) {
11383            // Any services running in the application need to be placed
11384            // back in the pending list.
11385            ServiceRecord sr = app.services.valueAt(i);
11386            sr.crashCount++;
11387        }
11388
11389        // If the crashing process is what we consider to be the "home process" and it has been
11390        // replaced by a third-party app, clear the package preferred activities from packages
11391        // with a home activity running in the process to prevent a repeatedly crashing app
11392        // from blocking the user to manually clear the list.
11393        final ArrayList<ActivityRecord> activities = app.activities;
11394        if (app == mHomeProcess && activities.size() > 0
11395                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
11396            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
11397                final ActivityRecord r = activities.get(activityNdx);
11398                if (r.isHomeActivity()) {
11399                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
11400                    try {
11401                        ActivityThread.getPackageManager()
11402                                .clearPackagePreferredActivities(r.packageName);
11403                    } catch (RemoteException c) {
11404                        // pm is in same process, this will never happen.
11405                    }
11406                }
11407            }
11408        }
11409
11410        if (!app.isolated) {
11411            // XXX Can't keep track of crash times for isolated processes,
11412            // because they don't have a perisistent identity.
11413            mProcessCrashTimes.put(app.info.processName, app.uid, now);
11414        }
11415
11416        if (app.crashHandler != null) mHandler.post(app.crashHandler);
11417        return true;
11418    }
11419
11420    void startAppProblemLocked(ProcessRecord app) {
11421        // If this app is not running under the current user, then we
11422        // can't give it a report button because that would require
11423        // launching the report UI under a different user.
11424        app.errorReportReceiver = null;
11425
11426        for (int userId : mCurrentProfileIds) {
11427            if (app.userId == userId) {
11428                app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
11429                        mContext, app.info.packageName, app.info.flags);
11430            }
11431        }
11432        skipCurrentReceiverLocked(app);
11433    }
11434
11435    void skipCurrentReceiverLocked(ProcessRecord app) {
11436        for (BroadcastQueue queue : mBroadcastQueues) {
11437            queue.skipCurrentReceiverLocked(app);
11438        }
11439    }
11440
11441    /**
11442     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
11443     * The application process will exit immediately after this call returns.
11444     * @param app object of the crashing app, null for the system server
11445     * @param crashInfo describing the exception
11446     */
11447    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
11448        ProcessRecord r = findAppProcess(app, "Crash");
11449        final String processName = app == null ? "system_server"
11450                : (r == null ? "unknown" : r.processName);
11451
11452        handleApplicationCrashInner("crash", r, processName, crashInfo);
11453    }
11454
11455    /* Native crash reporting uses this inner version because it needs to be somewhat
11456     * decoupled from the AM-managed cleanup lifecycle
11457     */
11458    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
11459            ApplicationErrorReport.CrashInfo crashInfo) {
11460        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
11461                UserHandle.getUserId(Binder.getCallingUid()), processName,
11462                r == null ? -1 : r.info.flags,
11463                crashInfo.exceptionClassName,
11464                crashInfo.exceptionMessage,
11465                crashInfo.throwFileName,
11466                crashInfo.throwLineNumber);
11467
11468        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
11469
11470        crashApplication(r, crashInfo);
11471    }
11472
11473    public void handleApplicationStrictModeViolation(
11474            IBinder app,
11475            int violationMask,
11476            StrictMode.ViolationInfo info) {
11477        ProcessRecord r = findAppProcess(app, "StrictMode");
11478        if (r == null) {
11479            return;
11480        }
11481
11482        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
11483            Integer stackFingerprint = info.hashCode();
11484            boolean logIt = true;
11485            synchronized (mAlreadyLoggedViolatedStacks) {
11486                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
11487                    logIt = false;
11488                    // TODO: sub-sample into EventLog for these, with
11489                    // the info.durationMillis?  Then we'd get
11490                    // the relative pain numbers, without logging all
11491                    // the stack traces repeatedly.  We'd want to do
11492                    // likewise in the client code, which also does
11493                    // dup suppression, before the Binder call.
11494                } else {
11495                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
11496                        mAlreadyLoggedViolatedStacks.clear();
11497                    }
11498                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
11499                }
11500            }
11501            if (logIt) {
11502                logStrictModeViolationToDropBox(r, info);
11503            }
11504        }
11505
11506        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
11507            AppErrorResult result = new AppErrorResult();
11508            synchronized (this) {
11509                final long origId = Binder.clearCallingIdentity();
11510
11511                Message msg = Message.obtain();
11512                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
11513                HashMap<String, Object> data = new HashMap<String, Object>();
11514                data.put("result", result);
11515                data.put("app", r);
11516                data.put("violationMask", violationMask);
11517                data.put("info", info);
11518                msg.obj = data;
11519                mHandler.sendMessage(msg);
11520
11521                Binder.restoreCallingIdentity(origId);
11522            }
11523            int res = result.get();
11524            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
11525        }
11526    }
11527
11528    // Depending on the policy in effect, there could be a bunch of
11529    // these in quick succession so we try to batch these together to
11530    // minimize disk writes, number of dropbox entries, and maximize
11531    // compression, by having more fewer, larger records.
11532    private void logStrictModeViolationToDropBox(
11533            ProcessRecord process,
11534            StrictMode.ViolationInfo info) {
11535        if (info == null) {
11536            return;
11537        }
11538        final boolean isSystemApp = process == null ||
11539                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
11540                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
11541        final String processName = process == null ? "unknown" : process.processName;
11542        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
11543        final DropBoxManager dbox = (DropBoxManager)
11544                mContext.getSystemService(Context.DROPBOX_SERVICE);
11545
11546        // Exit early if the dropbox isn't configured to accept this report type.
11547        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11548
11549        boolean bufferWasEmpty;
11550        boolean needsFlush;
11551        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
11552        synchronized (sb) {
11553            bufferWasEmpty = sb.length() == 0;
11554            appendDropBoxProcessHeaders(process, processName, sb);
11555            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11556            sb.append("System-App: ").append(isSystemApp).append("\n");
11557            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
11558            if (info.violationNumThisLoop != 0) {
11559                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
11560            }
11561            if (info.numAnimationsRunning != 0) {
11562                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
11563            }
11564            if (info.broadcastIntentAction != null) {
11565                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
11566            }
11567            if (info.durationMillis != -1) {
11568                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
11569            }
11570            if (info.numInstances != -1) {
11571                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
11572            }
11573            if (info.tags != null) {
11574                for (String tag : info.tags) {
11575                    sb.append("Span-Tag: ").append(tag).append("\n");
11576                }
11577            }
11578            sb.append("\n");
11579            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
11580                sb.append(info.crashInfo.stackTrace);
11581            }
11582            sb.append("\n");
11583
11584            // Only buffer up to ~64k.  Various logging bits truncate
11585            // things at 128k.
11586            needsFlush = (sb.length() > 64 * 1024);
11587        }
11588
11589        // Flush immediately if the buffer's grown too large, or this
11590        // is a non-system app.  Non-system apps are isolated with a
11591        // different tag & policy and not batched.
11592        //
11593        // Batching is useful during internal testing with
11594        // StrictMode settings turned up high.  Without batching,
11595        // thousands of separate files could be created on boot.
11596        if (!isSystemApp || needsFlush) {
11597            new Thread("Error dump: " + dropboxTag) {
11598                @Override
11599                public void run() {
11600                    String report;
11601                    synchronized (sb) {
11602                        report = sb.toString();
11603                        sb.delete(0, sb.length());
11604                        sb.trimToSize();
11605                    }
11606                    if (report.length() != 0) {
11607                        dbox.addText(dropboxTag, report);
11608                    }
11609                }
11610            }.start();
11611            return;
11612        }
11613
11614        // System app batching:
11615        if (!bufferWasEmpty) {
11616            // An existing dropbox-writing thread is outstanding, so
11617            // we don't need to start it up.  The existing thread will
11618            // catch the buffer appends we just did.
11619            return;
11620        }
11621
11622        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
11623        // (After this point, we shouldn't access AMS internal data structures.)
11624        new Thread("Error dump: " + dropboxTag) {
11625            @Override
11626            public void run() {
11627                // 5 second sleep to let stacks arrive and be batched together
11628                try {
11629                    Thread.sleep(5000);  // 5 seconds
11630                } catch (InterruptedException e) {}
11631
11632                String errorReport;
11633                synchronized (mStrictModeBuffer) {
11634                    errorReport = mStrictModeBuffer.toString();
11635                    if (errorReport.length() == 0) {
11636                        return;
11637                    }
11638                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
11639                    mStrictModeBuffer.trimToSize();
11640                }
11641                dbox.addText(dropboxTag, errorReport);
11642            }
11643        }.start();
11644    }
11645
11646    /**
11647     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
11648     * @param app object of the crashing app, null for the system server
11649     * @param tag reported by the caller
11650     * @param system whether this wtf is coming from the system
11651     * @param crashInfo describing the context of the error
11652     * @return true if the process should exit immediately (WTF is fatal)
11653     */
11654    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
11655            final ApplicationErrorReport.CrashInfo crashInfo) {
11656        final int callingUid = Binder.getCallingUid();
11657        final int callingPid = Binder.getCallingPid();
11658
11659        if (system) {
11660            // If this is coming from the system, we could very well have low-level
11661            // system locks held, so we want to do this all asynchronously.  And we
11662            // never want this to become fatal, so there is that too.
11663            mHandler.post(new Runnable() {
11664                @Override public void run() {
11665                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
11666                }
11667            });
11668            return false;
11669        }
11670
11671        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
11672                crashInfo);
11673
11674        if (r != null && r.pid != Process.myPid() &&
11675                Settings.Global.getInt(mContext.getContentResolver(),
11676                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
11677            crashApplication(r, crashInfo);
11678            return true;
11679        } else {
11680            return false;
11681        }
11682    }
11683
11684    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
11685            final ApplicationErrorReport.CrashInfo crashInfo) {
11686        final ProcessRecord r = findAppProcess(app, "WTF");
11687        final String processName = app == null ? "system_server"
11688                : (r == null ? "unknown" : r.processName);
11689
11690        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
11691                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
11692
11693        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
11694
11695        return r;
11696    }
11697
11698    /**
11699     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
11700     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
11701     */
11702    private ProcessRecord findAppProcess(IBinder app, String reason) {
11703        if (app == null) {
11704            return null;
11705        }
11706
11707        synchronized (this) {
11708            final int NP = mProcessNames.getMap().size();
11709            for (int ip=0; ip<NP; ip++) {
11710                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11711                final int NA = apps.size();
11712                for (int ia=0; ia<NA; ia++) {
11713                    ProcessRecord p = apps.valueAt(ia);
11714                    if (p.thread != null && p.thread.asBinder() == app) {
11715                        return p;
11716                    }
11717                }
11718            }
11719
11720            Slog.w(TAG, "Can't find mystery application for " + reason
11721                    + " from pid=" + Binder.getCallingPid()
11722                    + " uid=" + Binder.getCallingUid() + ": " + app);
11723            return null;
11724        }
11725    }
11726
11727    /**
11728     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
11729     * to append various headers to the dropbox log text.
11730     */
11731    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
11732            StringBuilder sb) {
11733        // Watchdog thread ends up invoking this function (with
11734        // a null ProcessRecord) to add the stack file to dropbox.
11735        // Do not acquire a lock on this (am) in such cases, as it
11736        // could cause a potential deadlock, if and when watchdog
11737        // is invoked due to unavailability of lock on am and it
11738        // would prevent watchdog from killing system_server.
11739        if (process == null) {
11740            sb.append("Process: ").append(processName).append("\n");
11741            return;
11742        }
11743        // Note: ProcessRecord 'process' is guarded by the service
11744        // instance.  (notably process.pkgList, which could otherwise change
11745        // concurrently during execution of this method)
11746        synchronized (this) {
11747            sb.append("Process: ").append(processName).append("\n");
11748            int flags = process.info.flags;
11749            IPackageManager pm = AppGlobals.getPackageManager();
11750            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
11751            for (int ip=0; ip<process.pkgList.size(); ip++) {
11752                String pkg = process.pkgList.keyAt(ip);
11753                sb.append("Package: ").append(pkg);
11754                try {
11755                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
11756                    if (pi != null) {
11757                        sb.append(" v").append(pi.versionCode);
11758                        if (pi.versionName != null) {
11759                            sb.append(" (").append(pi.versionName).append(")");
11760                        }
11761                    }
11762                } catch (RemoteException e) {
11763                    Slog.e(TAG, "Error getting package info: " + pkg, e);
11764                }
11765                sb.append("\n");
11766            }
11767        }
11768    }
11769
11770    private static String processClass(ProcessRecord process) {
11771        if (process == null || process.pid == MY_PID) {
11772            return "system_server";
11773        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
11774            return "system_app";
11775        } else {
11776            return "data_app";
11777        }
11778    }
11779
11780    /**
11781     * Write a description of an error (crash, WTF, ANR) to the drop box.
11782     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
11783     * @param process which caused the error, null means the system server
11784     * @param activity which triggered the error, null if unknown
11785     * @param parent activity related to the error, null if unknown
11786     * @param subject line related to the error, null if absent
11787     * @param report in long form describing the error, null if absent
11788     * @param logFile to include in the report, null if none
11789     * @param crashInfo giving an application stack trace, null if absent
11790     */
11791    public void addErrorToDropBox(String eventType,
11792            ProcessRecord process, String processName, ActivityRecord activity,
11793            ActivityRecord parent, String subject,
11794            final String report, final File logFile,
11795            final ApplicationErrorReport.CrashInfo crashInfo) {
11796        // NOTE -- this must never acquire the ActivityManagerService lock,
11797        // otherwise the watchdog may be prevented from resetting the system.
11798
11799        final String dropboxTag = processClass(process) + "_" + eventType;
11800        final DropBoxManager dbox = (DropBoxManager)
11801                mContext.getSystemService(Context.DROPBOX_SERVICE);
11802
11803        // Exit early if the dropbox isn't configured to accept this report type.
11804        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11805
11806        final StringBuilder sb = new StringBuilder(1024);
11807        appendDropBoxProcessHeaders(process, processName, sb);
11808        if (activity != null) {
11809            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
11810        }
11811        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
11812            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
11813        }
11814        if (parent != null && parent != activity) {
11815            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
11816        }
11817        if (subject != null) {
11818            sb.append("Subject: ").append(subject).append("\n");
11819        }
11820        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11821        if (Debug.isDebuggerConnected()) {
11822            sb.append("Debugger: Connected\n");
11823        }
11824        sb.append("\n");
11825
11826        // Do the rest in a worker thread to avoid blocking the caller on I/O
11827        // (After this point, we shouldn't access AMS internal data structures.)
11828        Thread worker = new Thread("Error dump: " + dropboxTag) {
11829            @Override
11830            public void run() {
11831                if (report != null) {
11832                    sb.append(report);
11833                }
11834                if (logFile != null) {
11835                    try {
11836                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
11837                                    "\n\n[[TRUNCATED]]"));
11838                    } catch (IOException e) {
11839                        Slog.e(TAG, "Error reading " + logFile, e);
11840                    }
11841                }
11842                if (crashInfo != null && crashInfo.stackTrace != null) {
11843                    sb.append(crashInfo.stackTrace);
11844                }
11845
11846                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
11847                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
11848                if (lines > 0) {
11849                    sb.append("\n");
11850
11851                    // Merge several logcat streams, and take the last N lines
11852                    InputStreamReader input = null;
11853                    try {
11854                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
11855                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
11856                                "-b", "crash",
11857                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
11858
11859                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
11860                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
11861                        input = new InputStreamReader(logcat.getInputStream());
11862
11863                        int num;
11864                        char[] buf = new char[8192];
11865                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
11866                    } catch (IOException e) {
11867                        Slog.e(TAG, "Error running logcat", e);
11868                    } finally {
11869                        if (input != null) try { input.close(); } catch (IOException e) {}
11870                    }
11871                }
11872
11873                dbox.addText(dropboxTag, sb.toString());
11874            }
11875        };
11876
11877        if (process == null) {
11878            // If process is null, we are being called from some internal code
11879            // and may be about to die -- run this synchronously.
11880            worker.run();
11881        } else {
11882            worker.start();
11883        }
11884    }
11885
11886    /**
11887     * Bring up the "unexpected error" dialog box for a crashing app.
11888     * Deal with edge cases (intercepts from instrumented applications,
11889     * ActivityController, error intent receivers, that sort of thing).
11890     * @param r the application crashing
11891     * @param crashInfo describing the failure
11892     */
11893    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
11894        long timeMillis = System.currentTimeMillis();
11895        String shortMsg = crashInfo.exceptionClassName;
11896        String longMsg = crashInfo.exceptionMessage;
11897        String stackTrace = crashInfo.stackTrace;
11898        if (shortMsg != null && longMsg != null) {
11899            longMsg = shortMsg + ": " + longMsg;
11900        } else if (shortMsg != null) {
11901            longMsg = shortMsg;
11902        }
11903
11904        AppErrorResult result = new AppErrorResult();
11905        synchronized (this) {
11906            if (mController != null) {
11907                try {
11908                    String name = r != null ? r.processName : null;
11909                    int pid = r != null ? r.pid : Binder.getCallingPid();
11910                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
11911                    if (!mController.appCrashed(name, pid,
11912                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
11913                        if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
11914                                && "Native crash".equals(crashInfo.exceptionClassName)) {
11915                            Slog.w(TAG, "Skip killing native crashed app " + name
11916                                    + "(" + pid + ") during testing");
11917                        } else {
11918                            Slog.w(TAG, "Force-killing crashed app " + name
11919                                    + " at watcher's request");
11920                            if (r != null) {
11921                                r.kill("crash", true);
11922                            } else {
11923                                // Huh.
11924                                Process.killProcess(pid);
11925                                Process.killProcessGroup(uid, pid);
11926                            }
11927                        }
11928                        return;
11929                    }
11930                } catch (RemoteException e) {
11931                    mController = null;
11932                    Watchdog.getInstance().setActivityController(null);
11933                }
11934            }
11935
11936            final long origId = Binder.clearCallingIdentity();
11937
11938            // If this process is running instrumentation, finish it.
11939            if (r != null && r.instrumentationClass != null) {
11940                Slog.w(TAG, "Error in app " + r.processName
11941                      + " running instrumentation " + r.instrumentationClass + ":");
11942                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
11943                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
11944                Bundle info = new Bundle();
11945                info.putString("shortMsg", shortMsg);
11946                info.putString("longMsg", longMsg);
11947                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
11948                Binder.restoreCallingIdentity(origId);
11949                return;
11950            }
11951
11952            // If we can't identify the process or it's already exceeded its crash quota,
11953            // quit right away without showing a crash dialog.
11954            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
11955                Binder.restoreCallingIdentity(origId);
11956                return;
11957            }
11958
11959            Message msg = Message.obtain();
11960            msg.what = SHOW_ERROR_MSG;
11961            HashMap data = new HashMap();
11962            data.put("result", result);
11963            data.put("app", r);
11964            msg.obj = data;
11965            mHandler.sendMessage(msg);
11966
11967            Binder.restoreCallingIdentity(origId);
11968        }
11969
11970        int res = result.get();
11971
11972        Intent appErrorIntent = null;
11973        synchronized (this) {
11974            if (r != null && !r.isolated) {
11975                // XXX Can't keep track of crash time for isolated processes,
11976                // since they don't have a persistent identity.
11977                mProcessCrashTimes.put(r.info.processName, r.uid,
11978                        SystemClock.uptimeMillis());
11979            }
11980            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
11981                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
11982            }
11983        }
11984
11985        if (appErrorIntent != null) {
11986            try {
11987                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
11988            } catch (ActivityNotFoundException e) {
11989                Slog.w(TAG, "bug report receiver dissappeared", e);
11990            }
11991        }
11992    }
11993
11994    Intent createAppErrorIntentLocked(ProcessRecord r,
11995            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
11996        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
11997        if (report == null) {
11998            return null;
11999        }
12000        Intent result = new Intent(Intent.ACTION_APP_ERROR);
12001        result.setComponent(r.errorReportReceiver);
12002        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
12003        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
12004        return result;
12005    }
12006
12007    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
12008            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12009        if (r.errorReportReceiver == null) {
12010            return null;
12011        }
12012
12013        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
12014            return null;
12015        }
12016
12017        ApplicationErrorReport report = new ApplicationErrorReport();
12018        report.packageName = r.info.packageName;
12019        report.installerPackageName = r.errorReportReceiver.getPackageName();
12020        report.processName = r.processName;
12021        report.time = timeMillis;
12022        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
12023
12024        if (r.crashing || r.forceCrashReport) {
12025            report.type = ApplicationErrorReport.TYPE_CRASH;
12026            report.crashInfo = crashInfo;
12027        } else if (r.notResponding) {
12028            report.type = ApplicationErrorReport.TYPE_ANR;
12029            report.anrInfo = new ApplicationErrorReport.AnrInfo();
12030
12031            report.anrInfo.activity = r.notRespondingReport.tag;
12032            report.anrInfo.cause = r.notRespondingReport.shortMsg;
12033            report.anrInfo.info = r.notRespondingReport.longMsg;
12034        }
12035
12036        return report;
12037    }
12038
12039    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
12040        enforceNotIsolatedCaller("getProcessesInErrorState");
12041        // assume our apps are happy - lazy create the list
12042        List<ActivityManager.ProcessErrorStateInfo> errList = null;
12043
12044        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12045                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12046        int userId = UserHandle.getUserId(Binder.getCallingUid());
12047
12048        synchronized (this) {
12049
12050            // iterate across all processes
12051            for (int i=mLruProcesses.size()-1; i>=0; i--) {
12052                ProcessRecord app = mLruProcesses.get(i);
12053                if (!allUsers && app.userId != userId) {
12054                    continue;
12055                }
12056                if ((app.thread != null) && (app.crashing || app.notResponding)) {
12057                    // This one's in trouble, so we'll generate a report for it
12058                    // crashes are higher priority (in case there's a crash *and* an anr)
12059                    ActivityManager.ProcessErrorStateInfo report = null;
12060                    if (app.crashing) {
12061                        report = app.crashingReport;
12062                    } else if (app.notResponding) {
12063                        report = app.notRespondingReport;
12064                    }
12065
12066                    if (report != null) {
12067                        if (errList == null) {
12068                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
12069                        }
12070                        errList.add(report);
12071                    } else {
12072                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
12073                                " crashing = " + app.crashing +
12074                                " notResponding = " + app.notResponding);
12075                    }
12076                }
12077            }
12078        }
12079
12080        return errList;
12081    }
12082
12083    static int procStateToImportance(int procState, int memAdj,
12084            ActivityManager.RunningAppProcessInfo currApp) {
12085        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
12086        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
12087            currApp.lru = memAdj;
12088        } else {
12089            currApp.lru = 0;
12090        }
12091        return imp;
12092    }
12093
12094    private void fillInProcMemInfo(ProcessRecord app,
12095            ActivityManager.RunningAppProcessInfo outInfo) {
12096        outInfo.pid = app.pid;
12097        outInfo.uid = app.info.uid;
12098        if (mHeavyWeightProcess == app) {
12099            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
12100        }
12101        if (app.persistent) {
12102            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
12103        }
12104        if (app.activities.size() > 0) {
12105            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
12106        }
12107        outInfo.lastTrimLevel = app.trimMemoryLevel;
12108        int adj = app.curAdj;
12109        int procState = app.curProcState;
12110        outInfo.importance = procStateToImportance(procState, adj, outInfo);
12111        outInfo.importanceReasonCode = app.adjTypeCode;
12112        outInfo.processState = app.curProcState;
12113    }
12114
12115    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
12116        enforceNotIsolatedCaller("getRunningAppProcesses");
12117        // Lazy instantiation of list
12118        List<ActivityManager.RunningAppProcessInfo> runList = null;
12119        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12120                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12121        int userId = UserHandle.getUserId(Binder.getCallingUid());
12122        synchronized (this) {
12123            // Iterate across all processes
12124            for (int i=mLruProcesses.size()-1; i>=0; i--) {
12125                ProcessRecord app = mLruProcesses.get(i);
12126                if (!allUsers && app.userId != userId) {
12127                    continue;
12128                }
12129                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
12130                    // Generate process state info for running application
12131                    ActivityManager.RunningAppProcessInfo currApp =
12132                        new ActivityManager.RunningAppProcessInfo(app.processName,
12133                                app.pid, app.getPackageList());
12134                    fillInProcMemInfo(app, currApp);
12135                    if (app.adjSource instanceof ProcessRecord) {
12136                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
12137                        currApp.importanceReasonImportance =
12138                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
12139                                        app.adjSourceProcState);
12140                    } else if (app.adjSource instanceof ActivityRecord) {
12141                        ActivityRecord r = (ActivityRecord)app.adjSource;
12142                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
12143                    }
12144                    if (app.adjTarget instanceof ComponentName) {
12145                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
12146                    }
12147                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
12148                    //        + " lru=" + currApp.lru);
12149                    if (runList == null) {
12150                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
12151                    }
12152                    runList.add(currApp);
12153                }
12154            }
12155        }
12156        return runList;
12157    }
12158
12159    public List<ApplicationInfo> getRunningExternalApplications() {
12160        enforceNotIsolatedCaller("getRunningExternalApplications");
12161        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
12162        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
12163        if (runningApps != null && runningApps.size() > 0) {
12164            Set<String> extList = new HashSet<String>();
12165            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
12166                if (app.pkgList != null) {
12167                    for (String pkg : app.pkgList) {
12168                        extList.add(pkg);
12169                    }
12170                }
12171            }
12172            IPackageManager pm = AppGlobals.getPackageManager();
12173            for (String pkg : extList) {
12174                try {
12175                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
12176                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
12177                        retList.add(info);
12178                    }
12179                } catch (RemoteException e) {
12180                }
12181            }
12182        }
12183        return retList;
12184    }
12185
12186    @Override
12187    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
12188        enforceNotIsolatedCaller("getMyMemoryState");
12189        synchronized (this) {
12190            ProcessRecord proc;
12191            synchronized (mPidsSelfLocked) {
12192                proc = mPidsSelfLocked.get(Binder.getCallingPid());
12193            }
12194            fillInProcMemInfo(proc, outInfo);
12195        }
12196    }
12197
12198    @Override
12199    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
12200        if (checkCallingPermission(android.Manifest.permission.DUMP)
12201                != PackageManager.PERMISSION_GRANTED) {
12202            pw.println("Permission Denial: can't dump ActivityManager from from pid="
12203                    + Binder.getCallingPid()
12204                    + ", uid=" + Binder.getCallingUid()
12205                    + " without permission "
12206                    + android.Manifest.permission.DUMP);
12207            return;
12208        }
12209
12210        boolean dumpAll = false;
12211        boolean dumpClient = false;
12212        String dumpPackage = null;
12213
12214        int opti = 0;
12215        while (opti < args.length) {
12216            String opt = args[opti];
12217            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12218                break;
12219            }
12220            opti++;
12221            if ("-a".equals(opt)) {
12222                dumpAll = true;
12223            } else if ("-c".equals(opt)) {
12224                dumpClient = true;
12225            } else if ("-h".equals(opt)) {
12226                pw.println("Activity manager dump options:");
12227                pw.println("  [-a] [-c] [-h] [cmd] ...");
12228                pw.println("  cmd may be one of:");
12229                pw.println("    a[ctivities]: activity stack state");
12230                pw.println("    r[recents]: recent activities state");
12231                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
12232                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
12233                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
12234                pw.println("    o[om]: out of memory management");
12235                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
12236                pw.println("    provider [COMP_SPEC]: provider client-side state");
12237                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
12238                pw.println("    service [COMP_SPEC]: service client-side state");
12239                pw.println("    package [PACKAGE_NAME]: all state related to given package");
12240                pw.println("    all: dump all activities");
12241                pw.println("    top: dump the top activity");
12242                pw.println("    write: write all pending state to storage");
12243                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
12244                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
12245                pw.println("    a partial substring in a component name, a");
12246                pw.println("    hex object identifier.");
12247                pw.println("  -a: include all available server state.");
12248                pw.println("  -c: include client state.");
12249                return;
12250            } else {
12251                pw.println("Unknown argument: " + opt + "; use -h for help");
12252            }
12253        }
12254
12255        long origId = Binder.clearCallingIdentity();
12256        boolean more = false;
12257        // Is the caller requesting to dump a particular piece of data?
12258        if (opti < args.length) {
12259            String cmd = args[opti];
12260            opti++;
12261            if ("activities".equals(cmd) || "a".equals(cmd)) {
12262                synchronized (this) {
12263                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
12264                }
12265            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
12266                synchronized (this) {
12267                    dumpRecentsLocked(fd, pw, args, opti, true, null);
12268                }
12269            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
12270                String[] newArgs;
12271                String name;
12272                if (opti >= args.length) {
12273                    name = null;
12274                    newArgs = EMPTY_STRING_ARRAY;
12275                } else {
12276                    name = args[opti];
12277                    opti++;
12278                    newArgs = new String[args.length - opti];
12279                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12280                            args.length - opti);
12281                }
12282                synchronized (this) {
12283                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
12284                }
12285            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
12286                String[] newArgs;
12287                String name;
12288                if (opti >= args.length) {
12289                    name = null;
12290                    newArgs = EMPTY_STRING_ARRAY;
12291                } else {
12292                    name = args[opti];
12293                    opti++;
12294                    newArgs = new String[args.length - opti];
12295                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12296                            args.length - opti);
12297                }
12298                synchronized (this) {
12299                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
12300                }
12301            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
12302                String[] newArgs;
12303                String name;
12304                if (opti >= args.length) {
12305                    name = null;
12306                    newArgs = EMPTY_STRING_ARRAY;
12307                } else {
12308                    name = args[opti];
12309                    opti++;
12310                    newArgs = new String[args.length - opti];
12311                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12312                            args.length - opti);
12313                }
12314                synchronized (this) {
12315                    dumpProcessesLocked(fd, pw, args, opti, true, name);
12316                }
12317            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
12318                synchronized (this) {
12319                    dumpOomLocked(fd, pw, args, opti, true);
12320                }
12321            } else if ("provider".equals(cmd)) {
12322                String[] newArgs;
12323                String name;
12324                if (opti >= args.length) {
12325                    name = null;
12326                    newArgs = EMPTY_STRING_ARRAY;
12327                } else {
12328                    name = args[opti];
12329                    opti++;
12330                    newArgs = new String[args.length - opti];
12331                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12332                }
12333                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
12334                    pw.println("No providers match: " + name);
12335                    pw.println("Use -h for help.");
12336                }
12337            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
12338                synchronized (this) {
12339                    dumpProvidersLocked(fd, pw, args, opti, true, null);
12340                }
12341            } else if ("service".equals(cmd)) {
12342                String[] newArgs;
12343                String name;
12344                if (opti >= args.length) {
12345                    name = null;
12346                    newArgs = EMPTY_STRING_ARRAY;
12347                } else {
12348                    name = args[opti];
12349                    opti++;
12350                    newArgs = new String[args.length - opti];
12351                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12352                            args.length - opti);
12353                }
12354                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
12355                    pw.println("No services match: " + name);
12356                    pw.println("Use -h for help.");
12357                }
12358            } else if ("package".equals(cmd)) {
12359                String[] newArgs;
12360                if (opti >= args.length) {
12361                    pw.println("package: no package name specified");
12362                    pw.println("Use -h for help.");
12363                } else {
12364                    dumpPackage = args[opti];
12365                    opti++;
12366                    newArgs = new String[args.length - opti];
12367                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12368                            args.length - opti);
12369                    args = newArgs;
12370                    opti = 0;
12371                    more = true;
12372                }
12373            } else if ("services".equals(cmd) || "s".equals(cmd)) {
12374                synchronized (this) {
12375                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
12376                }
12377            } else if ("write".equals(cmd)) {
12378                mTaskPersister.flush();
12379                pw.println("All tasks persisted.");
12380                return;
12381            } else {
12382                // Dumping a single activity?
12383                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
12384                    pw.println("Bad activity command, or no activities match: " + cmd);
12385                    pw.println("Use -h for help.");
12386                }
12387            }
12388            if (!more) {
12389                Binder.restoreCallingIdentity(origId);
12390                return;
12391            }
12392        }
12393
12394        // No piece of data specified, dump everything.
12395        synchronized (this) {
12396            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12397            pw.println();
12398            if (dumpAll) {
12399                pw.println("-------------------------------------------------------------------------------");
12400            }
12401            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12402            pw.println();
12403            if (dumpAll) {
12404                pw.println("-------------------------------------------------------------------------------");
12405            }
12406            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12407            pw.println();
12408            if (dumpAll) {
12409                pw.println("-------------------------------------------------------------------------------");
12410            }
12411            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12412            pw.println();
12413            if (dumpAll) {
12414                pw.println("-------------------------------------------------------------------------------");
12415            }
12416            dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12417            pw.println();
12418            if (dumpAll) {
12419                pw.println("-------------------------------------------------------------------------------");
12420            }
12421            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12422            pw.println();
12423            if (dumpAll) {
12424                pw.println("-------------------------------------------------------------------------------");
12425            }
12426            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12427        }
12428        Binder.restoreCallingIdentity(origId);
12429    }
12430
12431    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12432            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
12433        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
12434
12435        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
12436                dumpPackage);
12437        boolean needSep = printedAnything;
12438
12439        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
12440                dumpPackage, needSep, "  mFocusedActivity: ");
12441        if (printed) {
12442            printedAnything = true;
12443            needSep = false;
12444        }
12445
12446        if (dumpPackage == null) {
12447            if (needSep) {
12448                pw.println();
12449            }
12450            needSep = true;
12451            printedAnything = true;
12452            mStackSupervisor.dump(pw, "  ");
12453        }
12454
12455        if (!printedAnything) {
12456            pw.println("  (nothing)");
12457        }
12458    }
12459
12460    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12461            int opti, boolean dumpAll, String dumpPackage) {
12462        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
12463
12464        boolean printedAnything = false;
12465
12466        if (mRecentTasks != null && mRecentTasks.size() > 0) {
12467            boolean printedHeader = false;
12468
12469            final int N = mRecentTasks.size();
12470            for (int i=0; i<N; i++) {
12471                TaskRecord tr = mRecentTasks.get(i);
12472                if (dumpPackage != null) {
12473                    if (tr.realActivity == null ||
12474                            !dumpPackage.equals(tr.realActivity)) {
12475                        continue;
12476                    }
12477                }
12478                if (!printedHeader) {
12479                    pw.println("  Recent tasks:");
12480                    printedHeader = true;
12481                    printedAnything = true;
12482                }
12483                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
12484                        pw.println(tr);
12485                if (dumpAll) {
12486                    mRecentTasks.get(i).dump(pw, "    ");
12487                }
12488            }
12489        }
12490
12491        if (!printedAnything) {
12492            pw.println("  (nothing)");
12493        }
12494    }
12495
12496    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12497            int opti, boolean dumpAll, String dumpPackage) {
12498        boolean needSep = false;
12499        boolean printedAnything = false;
12500        int numPers = 0;
12501
12502        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
12503
12504        if (dumpAll) {
12505            final int NP = mProcessNames.getMap().size();
12506            for (int ip=0; ip<NP; ip++) {
12507                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
12508                final int NA = procs.size();
12509                for (int ia=0; ia<NA; ia++) {
12510                    ProcessRecord r = procs.valueAt(ia);
12511                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12512                        continue;
12513                    }
12514                    if (!needSep) {
12515                        pw.println("  All known processes:");
12516                        needSep = true;
12517                        printedAnything = true;
12518                    }
12519                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
12520                        pw.print(" UID "); pw.print(procs.keyAt(ia));
12521                        pw.print(" "); pw.println(r);
12522                    r.dump(pw, "    ");
12523                    if (r.persistent) {
12524                        numPers++;
12525                    }
12526                }
12527            }
12528        }
12529
12530        if (mIsolatedProcesses.size() > 0) {
12531            boolean printed = false;
12532            for (int i=0; i<mIsolatedProcesses.size(); i++) {
12533                ProcessRecord r = mIsolatedProcesses.valueAt(i);
12534                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12535                    continue;
12536                }
12537                if (!printed) {
12538                    if (needSep) {
12539                        pw.println();
12540                    }
12541                    pw.println("  Isolated process list (sorted by uid):");
12542                    printedAnything = true;
12543                    printed = true;
12544                    needSep = true;
12545                }
12546                pw.println(String.format("%sIsolated #%2d: %s",
12547                        "    ", i, r.toString()));
12548            }
12549        }
12550
12551        if (mLruProcesses.size() > 0) {
12552            if (needSep) {
12553                pw.println();
12554            }
12555            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
12556                    pw.print(" total, non-act at ");
12557                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12558                    pw.print(", non-svc at ");
12559                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12560                    pw.println("):");
12561            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
12562            needSep = true;
12563            printedAnything = true;
12564        }
12565
12566        if (dumpAll || dumpPackage != null) {
12567            synchronized (mPidsSelfLocked) {
12568                boolean printed = false;
12569                for (int i=0; i<mPidsSelfLocked.size(); i++) {
12570                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
12571                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12572                        continue;
12573                    }
12574                    if (!printed) {
12575                        if (needSep) pw.println();
12576                        needSep = true;
12577                        pw.println("  PID mappings:");
12578                        printed = true;
12579                        printedAnything = true;
12580                    }
12581                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
12582                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
12583                }
12584            }
12585        }
12586
12587        if (mForegroundProcesses.size() > 0) {
12588            synchronized (mPidsSelfLocked) {
12589                boolean printed = false;
12590                for (int i=0; i<mForegroundProcesses.size(); i++) {
12591                    ProcessRecord r = mPidsSelfLocked.get(
12592                            mForegroundProcesses.valueAt(i).pid);
12593                    if (dumpPackage != null && (r == null
12594                            || !r.pkgList.containsKey(dumpPackage))) {
12595                        continue;
12596                    }
12597                    if (!printed) {
12598                        if (needSep) pw.println();
12599                        needSep = true;
12600                        pw.println("  Foreground Processes:");
12601                        printed = true;
12602                        printedAnything = true;
12603                    }
12604                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
12605                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
12606                }
12607            }
12608        }
12609
12610        if (mPersistentStartingProcesses.size() > 0) {
12611            if (needSep) pw.println();
12612            needSep = true;
12613            printedAnything = true;
12614            pw.println("  Persisent processes that are starting:");
12615            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
12616                    "Starting Norm", "Restarting PERS", dumpPackage);
12617        }
12618
12619        if (mRemovedProcesses.size() > 0) {
12620            if (needSep) pw.println();
12621            needSep = true;
12622            printedAnything = true;
12623            pw.println("  Processes that are being removed:");
12624            dumpProcessList(pw, this, mRemovedProcesses, "    ",
12625                    "Removed Norm", "Removed PERS", dumpPackage);
12626        }
12627
12628        if (mProcessesOnHold.size() > 0) {
12629            if (needSep) pw.println();
12630            needSep = true;
12631            printedAnything = true;
12632            pw.println("  Processes that are on old until the system is ready:");
12633            dumpProcessList(pw, this, mProcessesOnHold, "    ",
12634                    "OnHold Norm", "OnHold PERS", dumpPackage);
12635        }
12636
12637        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
12638
12639        if (mProcessCrashTimes.getMap().size() > 0) {
12640            boolean printed = false;
12641            long now = SystemClock.uptimeMillis();
12642            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
12643            final int NP = pmap.size();
12644            for (int ip=0; ip<NP; ip++) {
12645                String pname = pmap.keyAt(ip);
12646                SparseArray<Long> uids = pmap.valueAt(ip);
12647                final int N = uids.size();
12648                for (int i=0; i<N; i++) {
12649                    int puid = uids.keyAt(i);
12650                    ProcessRecord r = mProcessNames.get(pname, puid);
12651                    if (dumpPackage != null && (r == null
12652                            || !r.pkgList.containsKey(dumpPackage))) {
12653                        continue;
12654                    }
12655                    if (!printed) {
12656                        if (needSep) pw.println();
12657                        needSep = true;
12658                        pw.println("  Time since processes crashed:");
12659                        printed = true;
12660                        printedAnything = true;
12661                    }
12662                    pw.print("    Process "); pw.print(pname);
12663                            pw.print(" uid "); pw.print(puid);
12664                            pw.print(": last crashed ");
12665                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
12666                            pw.println(" ago");
12667                }
12668            }
12669        }
12670
12671        if (mBadProcesses.getMap().size() > 0) {
12672            boolean printed = false;
12673            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
12674            final int NP = pmap.size();
12675            for (int ip=0; ip<NP; ip++) {
12676                String pname = pmap.keyAt(ip);
12677                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
12678                final int N = uids.size();
12679                for (int i=0; i<N; i++) {
12680                    int puid = uids.keyAt(i);
12681                    ProcessRecord r = mProcessNames.get(pname, puid);
12682                    if (dumpPackage != null && (r == null
12683                            || !r.pkgList.containsKey(dumpPackage))) {
12684                        continue;
12685                    }
12686                    if (!printed) {
12687                        if (needSep) pw.println();
12688                        needSep = true;
12689                        pw.println("  Bad processes:");
12690                        printedAnything = true;
12691                    }
12692                    BadProcessInfo info = uids.valueAt(i);
12693                    pw.print("    Bad process "); pw.print(pname);
12694                            pw.print(" uid "); pw.print(puid);
12695                            pw.print(": crashed at time "); pw.println(info.time);
12696                    if (info.shortMsg != null) {
12697                        pw.print("      Short msg: "); pw.println(info.shortMsg);
12698                    }
12699                    if (info.longMsg != null) {
12700                        pw.print("      Long msg: "); pw.println(info.longMsg);
12701                    }
12702                    if (info.stack != null) {
12703                        pw.println("      Stack:");
12704                        int lastPos = 0;
12705                        for (int pos=0; pos<info.stack.length(); pos++) {
12706                            if (info.stack.charAt(pos) == '\n') {
12707                                pw.print("        ");
12708                                pw.write(info.stack, lastPos, pos-lastPos);
12709                                pw.println();
12710                                lastPos = pos+1;
12711                            }
12712                        }
12713                        if (lastPos < info.stack.length()) {
12714                            pw.print("        ");
12715                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
12716                            pw.println();
12717                        }
12718                    }
12719                }
12720            }
12721        }
12722
12723        if (dumpPackage == null) {
12724            pw.println();
12725            needSep = false;
12726            pw.println("  mStartedUsers:");
12727            for (int i=0; i<mStartedUsers.size(); i++) {
12728                UserStartedState uss = mStartedUsers.valueAt(i);
12729                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
12730                        pw.print(": "); uss.dump("", pw);
12731            }
12732            pw.print("  mStartedUserArray: [");
12733            for (int i=0; i<mStartedUserArray.length; i++) {
12734                if (i > 0) pw.print(", ");
12735                pw.print(mStartedUserArray[i]);
12736            }
12737            pw.println("]");
12738            pw.print("  mUserLru: [");
12739            for (int i=0; i<mUserLru.size(); i++) {
12740                if (i > 0) pw.print(", ");
12741                pw.print(mUserLru.get(i));
12742            }
12743            pw.println("]");
12744            if (dumpAll) {
12745                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
12746            }
12747            synchronized (mUserProfileGroupIdsSelfLocked) {
12748                if (mUserProfileGroupIdsSelfLocked.size() > 0) {
12749                    pw.println("  mUserProfileGroupIds:");
12750                    for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
12751                        pw.print("    User #");
12752                        pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
12753                        pw.print(" -> profile #");
12754                        pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
12755                    }
12756                }
12757            }
12758        }
12759        if (mHomeProcess != null && (dumpPackage == null
12760                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
12761            if (needSep) {
12762                pw.println();
12763                needSep = false;
12764            }
12765            pw.println("  mHomeProcess: " + mHomeProcess);
12766        }
12767        if (mPreviousProcess != null && (dumpPackage == null
12768                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
12769            if (needSep) {
12770                pw.println();
12771                needSep = false;
12772            }
12773            pw.println("  mPreviousProcess: " + mPreviousProcess);
12774        }
12775        if (dumpAll) {
12776            StringBuilder sb = new StringBuilder(128);
12777            sb.append("  mPreviousProcessVisibleTime: ");
12778            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
12779            pw.println(sb);
12780        }
12781        if (mHeavyWeightProcess != null && (dumpPackage == null
12782                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
12783            if (needSep) {
12784                pw.println();
12785                needSep = false;
12786            }
12787            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12788        }
12789        if (dumpPackage == null) {
12790            pw.println("  mConfiguration: " + mConfiguration);
12791        }
12792        if (dumpAll) {
12793            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
12794            if (mCompatModePackages.getPackages().size() > 0) {
12795                boolean printed = false;
12796                for (Map.Entry<String, Integer> entry
12797                        : mCompatModePackages.getPackages().entrySet()) {
12798                    String pkg = entry.getKey();
12799                    int mode = entry.getValue();
12800                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
12801                        continue;
12802                    }
12803                    if (!printed) {
12804                        pw.println("  mScreenCompatPackages:");
12805                        printed = true;
12806                    }
12807                    pw.print("    "); pw.print(pkg); pw.print(": ");
12808                            pw.print(mode); pw.println();
12809                }
12810            }
12811        }
12812        if (dumpPackage == null) {
12813            if (mSleeping || mWentToSleep || mLockScreenShown != LOCK_SCREEN_HIDDEN) {
12814                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
12815                        + " mLockScreenShown " + lockScreenShownToString());
12816            }
12817            if (mShuttingDown || mRunningVoice) {
12818                pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
12819            }
12820        }
12821        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
12822                || mOrigWaitForDebugger) {
12823            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
12824                    || dumpPackage.equals(mOrigDebugApp)) {
12825                if (needSep) {
12826                    pw.println();
12827                    needSep = false;
12828                }
12829                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
12830                        + " mDebugTransient=" + mDebugTransient
12831                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
12832            }
12833        }
12834        if (mOpenGlTraceApp != null) {
12835            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
12836                if (needSep) {
12837                    pw.println();
12838                    needSep = false;
12839                }
12840                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
12841            }
12842        }
12843        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
12844                || mProfileFd != null) {
12845            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
12846                if (needSep) {
12847                    pw.println();
12848                    needSep = false;
12849                }
12850                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
12851                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
12852                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
12853                        + mAutoStopProfiler);
12854                pw.println("  mProfileType=" + mProfileType);
12855            }
12856        }
12857        if (dumpPackage == null) {
12858            if (mAlwaysFinishActivities || mController != null) {
12859                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
12860                        + " mController=" + mController);
12861            }
12862            if (dumpAll) {
12863                pw.println("  Total persistent processes: " + numPers);
12864                pw.println("  mProcessesReady=" + mProcessesReady
12865                        + " mSystemReady=" + mSystemReady
12866                        + " mBooted=" + mBooted
12867                        + " mFactoryTest=" + mFactoryTest);
12868                pw.println("  mBooting=" + mBooting
12869                        + " mCallFinishBooting=" + mCallFinishBooting
12870                        + " mBootAnimationComplete=" + mBootAnimationComplete);
12871                pw.print("  mLastPowerCheckRealtime=");
12872                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
12873                        pw.println("");
12874                pw.print("  mLastPowerCheckUptime=");
12875                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
12876                        pw.println("");
12877                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
12878                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
12879                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
12880                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
12881                        + " (" + mLruProcesses.size() + " total)"
12882                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
12883                        + " mNumServiceProcs=" + mNumServiceProcs
12884                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
12885                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
12886                        + " mLastMemoryLevel" + mLastMemoryLevel
12887                        + " mLastNumProcesses" + mLastNumProcesses);
12888                long now = SystemClock.uptimeMillis();
12889                pw.print("  mLastIdleTime=");
12890                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
12891                        pw.print(" mLowRamSinceLastIdle=");
12892                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
12893                        pw.println();
12894            }
12895        }
12896
12897        if (!printedAnything) {
12898            pw.println("  (nothing)");
12899        }
12900    }
12901
12902    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
12903            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
12904        if (mProcessesToGc.size() > 0) {
12905            boolean printed = false;
12906            long now = SystemClock.uptimeMillis();
12907            for (int i=0; i<mProcessesToGc.size(); i++) {
12908                ProcessRecord proc = mProcessesToGc.get(i);
12909                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
12910                    continue;
12911                }
12912                if (!printed) {
12913                    if (needSep) pw.println();
12914                    needSep = true;
12915                    pw.println("  Processes that are waiting to GC:");
12916                    printed = true;
12917                }
12918                pw.print("    Process "); pw.println(proc);
12919                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
12920                        pw.print(", last gced=");
12921                        pw.print(now-proc.lastRequestedGc);
12922                        pw.print(" ms ago, last lowMem=");
12923                        pw.print(now-proc.lastLowMemory);
12924                        pw.println(" ms ago");
12925
12926            }
12927        }
12928        return needSep;
12929    }
12930
12931    void printOomLevel(PrintWriter pw, String name, int adj) {
12932        pw.print("    ");
12933        if (adj >= 0) {
12934            pw.print(' ');
12935            if (adj < 10) pw.print(' ');
12936        } else {
12937            if (adj > -10) pw.print(' ');
12938        }
12939        pw.print(adj);
12940        pw.print(": ");
12941        pw.print(name);
12942        pw.print(" (");
12943        pw.print(mProcessList.getMemLevel(adj)/1024);
12944        pw.println(" kB)");
12945    }
12946
12947    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12948            int opti, boolean dumpAll) {
12949        boolean needSep = false;
12950
12951        if (mLruProcesses.size() > 0) {
12952            if (needSep) pw.println();
12953            needSep = true;
12954            pw.println("  OOM levels:");
12955            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
12956            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
12957            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
12958            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
12959            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
12960            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
12961            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
12962            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
12963            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
12964            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
12965            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
12966            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
12967            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
12968            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
12969
12970            if (needSep) pw.println();
12971            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
12972                    pw.print(" total, non-act at ");
12973                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12974                    pw.print(", non-svc at ");
12975                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12976                    pw.println("):");
12977            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
12978            needSep = true;
12979        }
12980
12981        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
12982
12983        pw.println();
12984        pw.println("  mHomeProcess: " + mHomeProcess);
12985        pw.println("  mPreviousProcess: " + mPreviousProcess);
12986        if (mHeavyWeightProcess != null) {
12987            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12988        }
12989
12990        return true;
12991    }
12992
12993    /**
12994     * There are three ways to call this:
12995     *  - no provider specified: dump all the providers
12996     *  - a flattened component name that matched an existing provider was specified as the
12997     *    first arg: dump that one provider
12998     *  - the first arg isn't the flattened component name of an existing provider:
12999     *    dump all providers whose component contains the first arg as a substring
13000     */
13001    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13002            int opti, boolean dumpAll) {
13003        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
13004    }
13005
13006    static class ItemMatcher {
13007        ArrayList<ComponentName> components;
13008        ArrayList<String> strings;
13009        ArrayList<Integer> objects;
13010        boolean all;
13011
13012        ItemMatcher() {
13013            all = true;
13014        }
13015
13016        void build(String name) {
13017            ComponentName componentName = ComponentName.unflattenFromString(name);
13018            if (componentName != null) {
13019                if (components == null) {
13020                    components = new ArrayList<ComponentName>();
13021                }
13022                components.add(componentName);
13023                all = false;
13024            } else {
13025                int objectId = 0;
13026                // Not a '/' separated full component name; maybe an object ID?
13027                try {
13028                    objectId = Integer.parseInt(name, 16);
13029                    if (objects == null) {
13030                        objects = new ArrayList<Integer>();
13031                    }
13032                    objects.add(objectId);
13033                    all = false;
13034                } catch (RuntimeException e) {
13035                    // Not an integer; just do string match.
13036                    if (strings == null) {
13037                        strings = new ArrayList<String>();
13038                    }
13039                    strings.add(name);
13040                    all = false;
13041                }
13042            }
13043        }
13044
13045        int build(String[] args, int opti) {
13046            for (; opti<args.length; opti++) {
13047                String name = args[opti];
13048                if ("--".equals(name)) {
13049                    return opti+1;
13050                }
13051                build(name);
13052            }
13053            return opti;
13054        }
13055
13056        boolean match(Object object, ComponentName comp) {
13057            if (all) {
13058                return true;
13059            }
13060            if (components != null) {
13061                for (int i=0; i<components.size(); i++) {
13062                    if (components.get(i).equals(comp)) {
13063                        return true;
13064                    }
13065                }
13066            }
13067            if (objects != null) {
13068                for (int i=0; i<objects.size(); i++) {
13069                    if (System.identityHashCode(object) == objects.get(i)) {
13070                        return true;
13071                    }
13072                }
13073            }
13074            if (strings != null) {
13075                String flat = comp.flattenToString();
13076                for (int i=0; i<strings.size(); i++) {
13077                    if (flat.contains(strings.get(i))) {
13078                        return true;
13079                    }
13080                }
13081            }
13082            return false;
13083        }
13084    }
13085
13086    /**
13087     * There are three things that cmd can be:
13088     *  - a flattened component name that matches an existing activity
13089     *  - the cmd arg isn't the flattened component name of an existing activity:
13090     *    dump all activity whose component contains the cmd as a substring
13091     *  - A hex number of the ActivityRecord object instance.
13092     */
13093    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13094            int opti, boolean dumpAll) {
13095        ArrayList<ActivityRecord> activities;
13096
13097        synchronized (this) {
13098            activities = mStackSupervisor.getDumpActivitiesLocked(name);
13099        }
13100
13101        if (activities.size() <= 0) {
13102            return false;
13103        }
13104
13105        String[] newArgs = new String[args.length - opti];
13106        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13107
13108        TaskRecord lastTask = null;
13109        boolean needSep = false;
13110        for (int i=activities.size()-1; i>=0; i--) {
13111            ActivityRecord r = activities.get(i);
13112            if (needSep) {
13113                pw.println();
13114            }
13115            needSep = true;
13116            synchronized (this) {
13117                if (lastTask != r.task) {
13118                    lastTask = r.task;
13119                    pw.print("TASK "); pw.print(lastTask.affinity);
13120                            pw.print(" id="); pw.println(lastTask.taskId);
13121                    if (dumpAll) {
13122                        lastTask.dump(pw, "  ");
13123                    }
13124                }
13125            }
13126            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
13127        }
13128        return true;
13129    }
13130
13131    /**
13132     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
13133     * there is a thread associated with the activity.
13134     */
13135    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
13136            final ActivityRecord r, String[] args, boolean dumpAll) {
13137        String innerPrefix = prefix + "  ";
13138        synchronized (this) {
13139            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
13140                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
13141                    pw.print(" pid=");
13142                    if (r.app != null) pw.println(r.app.pid);
13143                    else pw.println("(not running)");
13144            if (dumpAll) {
13145                r.dump(pw, innerPrefix);
13146            }
13147        }
13148        if (r.app != null && r.app.thread != null) {
13149            // flush anything that is already in the PrintWriter since the thread is going
13150            // to write to the file descriptor directly
13151            pw.flush();
13152            try {
13153                TransferPipe tp = new TransferPipe();
13154                try {
13155                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
13156                            r.appToken, innerPrefix, args);
13157                    tp.go(fd);
13158                } finally {
13159                    tp.kill();
13160                }
13161            } catch (IOException e) {
13162                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
13163            } catch (RemoteException e) {
13164                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
13165            }
13166        }
13167    }
13168
13169    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13170            int opti, boolean dumpAll, String dumpPackage) {
13171        boolean needSep = false;
13172        boolean onlyHistory = false;
13173        boolean printedAnything = false;
13174
13175        if ("history".equals(dumpPackage)) {
13176            if (opti < args.length && "-s".equals(args[opti])) {
13177                dumpAll = false;
13178            }
13179            onlyHistory = true;
13180            dumpPackage = null;
13181        }
13182
13183        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
13184        if (!onlyHistory && dumpAll) {
13185            if (mRegisteredReceivers.size() > 0) {
13186                boolean printed = false;
13187                Iterator it = mRegisteredReceivers.values().iterator();
13188                while (it.hasNext()) {
13189                    ReceiverList r = (ReceiverList)it.next();
13190                    if (dumpPackage != null && (r.app == null ||
13191                            !dumpPackage.equals(r.app.info.packageName))) {
13192                        continue;
13193                    }
13194                    if (!printed) {
13195                        pw.println("  Registered Receivers:");
13196                        needSep = true;
13197                        printed = true;
13198                        printedAnything = true;
13199                    }
13200                    pw.print("  * "); pw.println(r);
13201                    r.dump(pw, "    ");
13202                }
13203            }
13204
13205            if (mReceiverResolver.dump(pw, needSep ?
13206                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
13207                    "    ", dumpPackage, false)) {
13208                needSep = true;
13209                printedAnything = true;
13210            }
13211        }
13212
13213        for (BroadcastQueue q : mBroadcastQueues) {
13214            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
13215            printedAnything |= needSep;
13216        }
13217
13218        needSep = true;
13219
13220        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
13221            for (int user=0; user<mStickyBroadcasts.size(); user++) {
13222                if (needSep) {
13223                    pw.println();
13224                }
13225                needSep = true;
13226                printedAnything = true;
13227                pw.print("  Sticky broadcasts for user ");
13228                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
13229                StringBuilder sb = new StringBuilder(128);
13230                for (Map.Entry<String, ArrayList<Intent>> ent
13231                        : mStickyBroadcasts.valueAt(user).entrySet()) {
13232                    pw.print("  * Sticky action "); pw.print(ent.getKey());
13233                    if (dumpAll) {
13234                        pw.println(":");
13235                        ArrayList<Intent> intents = ent.getValue();
13236                        final int N = intents.size();
13237                        for (int i=0; i<N; i++) {
13238                            sb.setLength(0);
13239                            sb.append("    Intent: ");
13240                            intents.get(i).toShortString(sb, false, true, false, false);
13241                            pw.println(sb.toString());
13242                            Bundle bundle = intents.get(i).getExtras();
13243                            if (bundle != null) {
13244                                pw.print("      ");
13245                                pw.println(bundle.toString());
13246                            }
13247                        }
13248                    } else {
13249                        pw.println("");
13250                    }
13251                }
13252            }
13253        }
13254
13255        if (!onlyHistory && dumpAll) {
13256            pw.println();
13257            for (BroadcastQueue queue : mBroadcastQueues) {
13258                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
13259                        + queue.mBroadcastsScheduled);
13260            }
13261            pw.println("  mHandler:");
13262            mHandler.dump(new PrintWriterPrinter(pw), "    ");
13263            needSep = true;
13264            printedAnything = true;
13265        }
13266
13267        if (!printedAnything) {
13268            pw.println("  (nothing)");
13269        }
13270    }
13271
13272    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13273            int opti, boolean dumpAll, String dumpPackage) {
13274        boolean needSep;
13275        boolean printedAnything = false;
13276
13277        ItemMatcher matcher = new ItemMatcher();
13278        matcher.build(args, opti);
13279
13280        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
13281
13282        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
13283        printedAnything |= needSep;
13284
13285        if (mLaunchingProviders.size() > 0) {
13286            boolean printed = false;
13287            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
13288                ContentProviderRecord r = mLaunchingProviders.get(i);
13289                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
13290                    continue;
13291                }
13292                if (!printed) {
13293                    if (needSep) pw.println();
13294                    needSep = true;
13295                    pw.println("  Launching content providers:");
13296                    printed = true;
13297                    printedAnything = true;
13298                }
13299                pw.print("  Launching #"); pw.print(i); pw.print(": ");
13300                        pw.println(r);
13301            }
13302        }
13303
13304        if (mGrantedUriPermissions.size() > 0) {
13305            boolean printed = false;
13306            int dumpUid = -2;
13307            if (dumpPackage != null) {
13308                try {
13309                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
13310                } catch (NameNotFoundException e) {
13311                    dumpUid = -1;
13312                }
13313            }
13314            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
13315                int uid = mGrantedUriPermissions.keyAt(i);
13316                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
13317                    continue;
13318                }
13319                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
13320                if (!printed) {
13321                    if (needSep) pw.println();
13322                    needSep = true;
13323                    pw.println("  Granted Uri Permissions:");
13324                    printed = true;
13325                    printedAnything = true;
13326                }
13327                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
13328                for (UriPermission perm : perms.values()) {
13329                    pw.print("    "); pw.println(perm);
13330                    if (dumpAll) {
13331                        perm.dump(pw, "      ");
13332                    }
13333                }
13334            }
13335        }
13336
13337        if (!printedAnything) {
13338            pw.println("  (nothing)");
13339        }
13340    }
13341
13342    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13343            int opti, boolean dumpAll, String dumpPackage) {
13344        boolean printed = false;
13345
13346        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
13347
13348        if (mIntentSenderRecords.size() > 0) {
13349            Iterator<WeakReference<PendingIntentRecord>> it
13350                    = mIntentSenderRecords.values().iterator();
13351            while (it.hasNext()) {
13352                WeakReference<PendingIntentRecord> ref = it.next();
13353                PendingIntentRecord rec = ref != null ? ref.get(): null;
13354                if (dumpPackage != null && (rec == null
13355                        || !dumpPackage.equals(rec.key.packageName))) {
13356                    continue;
13357                }
13358                printed = true;
13359                if (rec != null) {
13360                    pw.print("  * "); pw.println(rec);
13361                    if (dumpAll) {
13362                        rec.dump(pw, "    ");
13363                    }
13364                } else {
13365                    pw.print("  * "); pw.println(ref);
13366                }
13367            }
13368        }
13369
13370        if (!printed) {
13371            pw.println("  (nothing)");
13372        }
13373    }
13374
13375    private static final int dumpProcessList(PrintWriter pw,
13376            ActivityManagerService service, List list,
13377            String prefix, String normalLabel, String persistentLabel,
13378            String dumpPackage) {
13379        int numPers = 0;
13380        final int N = list.size()-1;
13381        for (int i=N; i>=0; i--) {
13382            ProcessRecord r = (ProcessRecord)list.get(i);
13383            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
13384                continue;
13385            }
13386            pw.println(String.format("%s%s #%2d: %s",
13387                    prefix, (r.persistent ? persistentLabel : normalLabel),
13388                    i, r.toString()));
13389            if (r.persistent) {
13390                numPers++;
13391            }
13392        }
13393        return numPers;
13394    }
13395
13396    private static final boolean dumpProcessOomList(PrintWriter pw,
13397            ActivityManagerService service, List<ProcessRecord> origList,
13398            String prefix, String normalLabel, String persistentLabel,
13399            boolean inclDetails, String dumpPackage) {
13400
13401        ArrayList<Pair<ProcessRecord, Integer>> list
13402                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
13403        for (int i=0; i<origList.size(); i++) {
13404            ProcessRecord r = origList.get(i);
13405            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13406                continue;
13407            }
13408            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
13409        }
13410
13411        if (list.size() <= 0) {
13412            return false;
13413        }
13414
13415        Comparator<Pair<ProcessRecord, Integer>> comparator
13416                = new Comparator<Pair<ProcessRecord, Integer>>() {
13417            @Override
13418            public int compare(Pair<ProcessRecord, Integer> object1,
13419                    Pair<ProcessRecord, Integer> object2) {
13420                if (object1.first.setAdj != object2.first.setAdj) {
13421                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
13422                }
13423                if (object1.second.intValue() != object2.second.intValue()) {
13424                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
13425                }
13426                return 0;
13427            }
13428        };
13429
13430        Collections.sort(list, comparator);
13431
13432        final long curRealtime = SystemClock.elapsedRealtime();
13433        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
13434        final long curUptime = SystemClock.uptimeMillis();
13435        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
13436
13437        for (int i=list.size()-1; i>=0; i--) {
13438            ProcessRecord r = list.get(i).first;
13439            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
13440            char schedGroup;
13441            switch (r.setSchedGroup) {
13442                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
13443                    schedGroup = 'B';
13444                    break;
13445                case Process.THREAD_GROUP_DEFAULT:
13446                    schedGroup = 'F';
13447                    break;
13448                default:
13449                    schedGroup = '?';
13450                    break;
13451            }
13452            char foreground;
13453            if (r.foregroundActivities) {
13454                foreground = 'A';
13455            } else if (r.foregroundServices) {
13456                foreground = 'S';
13457            } else {
13458                foreground = ' ';
13459            }
13460            String procState = ProcessList.makeProcStateString(r.curProcState);
13461            pw.print(prefix);
13462            pw.print(r.persistent ? persistentLabel : normalLabel);
13463            pw.print(" #");
13464            int num = (origList.size()-1)-list.get(i).second;
13465            if (num < 10) pw.print(' ');
13466            pw.print(num);
13467            pw.print(": ");
13468            pw.print(oomAdj);
13469            pw.print(' ');
13470            pw.print(schedGroup);
13471            pw.print('/');
13472            pw.print(foreground);
13473            pw.print('/');
13474            pw.print(procState);
13475            pw.print(" trm:");
13476            if (r.trimMemoryLevel < 10) pw.print(' ');
13477            pw.print(r.trimMemoryLevel);
13478            pw.print(' ');
13479            pw.print(r.toShortString());
13480            pw.print(" (");
13481            pw.print(r.adjType);
13482            pw.println(')');
13483            if (r.adjSource != null || r.adjTarget != null) {
13484                pw.print(prefix);
13485                pw.print("    ");
13486                if (r.adjTarget instanceof ComponentName) {
13487                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
13488                } else if (r.adjTarget != null) {
13489                    pw.print(r.adjTarget.toString());
13490                } else {
13491                    pw.print("{null}");
13492                }
13493                pw.print("<=");
13494                if (r.adjSource instanceof ProcessRecord) {
13495                    pw.print("Proc{");
13496                    pw.print(((ProcessRecord)r.adjSource).toShortString());
13497                    pw.println("}");
13498                } else if (r.adjSource != null) {
13499                    pw.println(r.adjSource.toString());
13500                } else {
13501                    pw.println("{null}");
13502                }
13503            }
13504            if (inclDetails) {
13505                pw.print(prefix);
13506                pw.print("    ");
13507                pw.print("oom: max="); pw.print(r.maxAdj);
13508                pw.print(" curRaw="); pw.print(r.curRawAdj);
13509                pw.print(" setRaw="); pw.print(r.setRawAdj);
13510                pw.print(" cur="); pw.print(r.curAdj);
13511                pw.print(" set="); pw.println(r.setAdj);
13512                pw.print(prefix);
13513                pw.print("    ");
13514                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
13515                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
13516                pw.print(" lastPss="); pw.print(r.lastPss);
13517                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
13518                pw.print(prefix);
13519                pw.print("    ");
13520                pw.print("cached="); pw.print(r.cached);
13521                pw.print(" empty="); pw.print(r.empty);
13522                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
13523
13524                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
13525                    if (r.lastWakeTime != 0) {
13526                        long wtime;
13527                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
13528                        synchronized (stats) {
13529                            wtime = stats.getProcessWakeTime(r.info.uid,
13530                                    r.pid, curRealtime);
13531                        }
13532                        long timeUsed = wtime - r.lastWakeTime;
13533                        pw.print(prefix);
13534                        pw.print("    ");
13535                        pw.print("keep awake over ");
13536                        TimeUtils.formatDuration(realtimeSince, pw);
13537                        pw.print(" used ");
13538                        TimeUtils.formatDuration(timeUsed, pw);
13539                        pw.print(" (");
13540                        pw.print((timeUsed*100)/realtimeSince);
13541                        pw.println("%)");
13542                    }
13543                    if (r.lastCpuTime != 0) {
13544                        long timeUsed = r.curCpuTime - r.lastCpuTime;
13545                        pw.print(prefix);
13546                        pw.print("    ");
13547                        pw.print("run cpu over ");
13548                        TimeUtils.formatDuration(uptimeSince, pw);
13549                        pw.print(" used ");
13550                        TimeUtils.formatDuration(timeUsed, pw);
13551                        pw.print(" (");
13552                        pw.print((timeUsed*100)/uptimeSince);
13553                        pw.println("%)");
13554                    }
13555                }
13556            }
13557        }
13558        return true;
13559    }
13560
13561    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
13562            String[] args) {
13563        ArrayList<ProcessRecord> procs;
13564        synchronized (this) {
13565            if (args != null && args.length > start
13566                    && args[start].charAt(0) != '-') {
13567                procs = new ArrayList<ProcessRecord>();
13568                int pid = -1;
13569                try {
13570                    pid = Integer.parseInt(args[start]);
13571                } catch (NumberFormatException e) {
13572                }
13573                for (int i=mLruProcesses.size()-1; i>=0; i--) {
13574                    ProcessRecord proc = mLruProcesses.get(i);
13575                    if (proc.pid == pid) {
13576                        procs.add(proc);
13577                    } else if (allPkgs && proc.pkgList != null
13578                            && proc.pkgList.containsKey(args[start])) {
13579                        procs.add(proc);
13580                    } else if (proc.processName.equals(args[start])) {
13581                        procs.add(proc);
13582                    }
13583                }
13584                if (procs.size() <= 0) {
13585                    return null;
13586                }
13587            } else {
13588                procs = new ArrayList<ProcessRecord>(mLruProcesses);
13589            }
13590        }
13591        return procs;
13592    }
13593
13594    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
13595            PrintWriter pw, String[] args) {
13596        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
13597        if (procs == null) {
13598            pw.println("No process found for: " + args[0]);
13599            return;
13600        }
13601
13602        long uptime = SystemClock.uptimeMillis();
13603        long realtime = SystemClock.elapsedRealtime();
13604        pw.println("Applications Graphics Acceleration Info:");
13605        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13606
13607        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13608            ProcessRecord r = procs.get(i);
13609            if (r.thread != null) {
13610                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
13611                pw.flush();
13612                try {
13613                    TransferPipe tp = new TransferPipe();
13614                    try {
13615                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
13616                        tp.go(fd);
13617                    } finally {
13618                        tp.kill();
13619                    }
13620                } catch (IOException e) {
13621                    pw.println("Failure while dumping the app: " + r);
13622                    pw.flush();
13623                } catch (RemoteException e) {
13624                    pw.println("Got a RemoteException while dumping the app " + r);
13625                    pw.flush();
13626                }
13627            }
13628        }
13629    }
13630
13631    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
13632        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
13633        if (procs == null) {
13634            pw.println("No process found for: " + args[0]);
13635            return;
13636        }
13637
13638        pw.println("Applications Database Info:");
13639
13640        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13641            ProcessRecord r = procs.get(i);
13642            if (r.thread != null) {
13643                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
13644                pw.flush();
13645                try {
13646                    TransferPipe tp = new TransferPipe();
13647                    try {
13648                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
13649                        tp.go(fd);
13650                    } finally {
13651                        tp.kill();
13652                    }
13653                } catch (IOException e) {
13654                    pw.println("Failure while dumping the app: " + r);
13655                    pw.flush();
13656                } catch (RemoteException e) {
13657                    pw.println("Got a RemoteException while dumping the app " + r);
13658                    pw.flush();
13659                }
13660            }
13661        }
13662    }
13663
13664    final static class MemItem {
13665        final boolean isProc;
13666        final String label;
13667        final String shortLabel;
13668        final long pss;
13669        final int id;
13670        final boolean hasActivities;
13671        ArrayList<MemItem> subitems;
13672
13673        public MemItem(String _label, String _shortLabel, long _pss, int _id,
13674                boolean _hasActivities) {
13675            isProc = true;
13676            label = _label;
13677            shortLabel = _shortLabel;
13678            pss = _pss;
13679            id = _id;
13680            hasActivities = _hasActivities;
13681        }
13682
13683        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
13684            isProc = false;
13685            label = _label;
13686            shortLabel = _shortLabel;
13687            pss = _pss;
13688            id = _id;
13689            hasActivities = false;
13690        }
13691    }
13692
13693    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
13694            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
13695        if (sort && !isCompact) {
13696            Collections.sort(items, new Comparator<MemItem>() {
13697                @Override
13698                public int compare(MemItem lhs, MemItem rhs) {
13699                    if (lhs.pss < rhs.pss) {
13700                        return 1;
13701                    } else if (lhs.pss > rhs.pss) {
13702                        return -1;
13703                    }
13704                    return 0;
13705                }
13706            });
13707        }
13708
13709        for (int i=0; i<items.size(); i++) {
13710            MemItem mi = items.get(i);
13711            if (!isCompact) {
13712                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
13713            } else if (mi.isProc) {
13714                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
13715                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
13716                pw.println(mi.hasActivities ? ",a" : ",e");
13717            } else {
13718                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
13719                pw.println(mi.pss);
13720            }
13721            if (mi.subitems != null) {
13722                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
13723                        true, isCompact);
13724            }
13725        }
13726    }
13727
13728    // These are in KB.
13729    static final long[] DUMP_MEM_BUCKETS = new long[] {
13730        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
13731        120*1024, 160*1024, 200*1024,
13732        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
13733        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
13734    };
13735
13736    static final void appendMemBucket(StringBuilder out, long memKB, String label,
13737            boolean stackLike) {
13738        int start = label.lastIndexOf('.');
13739        if (start >= 0) start++;
13740        else start = 0;
13741        int end = label.length();
13742        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
13743            if (DUMP_MEM_BUCKETS[i] >= memKB) {
13744                long bucket = DUMP_MEM_BUCKETS[i]/1024;
13745                out.append(bucket);
13746                out.append(stackLike ? "MB." : "MB ");
13747                out.append(label, start, end);
13748                return;
13749            }
13750        }
13751        out.append(memKB/1024);
13752        out.append(stackLike ? "MB." : "MB ");
13753        out.append(label, start, end);
13754    }
13755
13756    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
13757            ProcessList.NATIVE_ADJ,
13758            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
13759            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
13760            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
13761            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
13762            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
13763            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
13764    };
13765    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
13766            "Native",
13767            "System", "Persistent", "Persistent Service", "Foreground",
13768            "Visible", "Perceptible",
13769            "Heavy Weight", "Backup",
13770            "A Services", "Home",
13771            "Previous", "B Services", "Cached"
13772    };
13773    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
13774            "native",
13775            "sys", "pers", "persvc", "fore",
13776            "vis", "percept",
13777            "heavy", "backup",
13778            "servicea", "home",
13779            "prev", "serviceb", "cached"
13780    };
13781
13782    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
13783            long realtime, boolean isCheckinRequest, boolean isCompact) {
13784        if (isCheckinRequest || isCompact) {
13785            // short checkin version
13786            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
13787        } else {
13788            pw.println("Applications Memory Usage (kB):");
13789            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13790        }
13791    }
13792
13793    private static final int KSM_SHARED = 0;
13794    private static final int KSM_SHARING = 1;
13795    private static final int KSM_UNSHARED = 2;
13796    private static final int KSM_VOLATILE = 3;
13797
13798    private final long[] getKsmInfo() {
13799        long[] longOut = new long[4];
13800        final int[] SINGLE_LONG_FORMAT = new int[] {
13801            Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
13802        };
13803        long[] longTmp = new long[1];
13804        Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
13805                SINGLE_LONG_FORMAT, null, longTmp, null);
13806        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
13807        longTmp[0] = 0;
13808        Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
13809                SINGLE_LONG_FORMAT, null, longTmp, null);
13810        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
13811        longTmp[0] = 0;
13812        Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
13813                SINGLE_LONG_FORMAT, null, longTmp, null);
13814        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
13815        longTmp[0] = 0;
13816        Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
13817                SINGLE_LONG_FORMAT, null, longTmp, null);
13818        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
13819        return longOut;
13820    }
13821
13822    final void dumpApplicationMemoryUsage(FileDescriptor fd,
13823            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
13824        boolean dumpDetails = false;
13825        boolean dumpFullDetails = false;
13826        boolean dumpDalvik = false;
13827        boolean oomOnly = false;
13828        boolean isCompact = false;
13829        boolean localOnly = false;
13830        boolean packages = false;
13831
13832        int opti = 0;
13833        while (opti < args.length) {
13834            String opt = args[opti];
13835            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13836                break;
13837            }
13838            opti++;
13839            if ("-a".equals(opt)) {
13840                dumpDetails = true;
13841                dumpFullDetails = true;
13842                dumpDalvik = true;
13843            } else if ("-d".equals(opt)) {
13844                dumpDalvik = true;
13845            } else if ("-c".equals(opt)) {
13846                isCompact = true;
13847            } else if ("--oom".equals(opt)) {
13848                oomOnly = true;
13849            } else if ("--local".equals(opt)) {
13850                localOnly = true;
13851            } else if ("--package".equals(opt)) {
13852                packages = true;
13853            } else if ("-h".equals(opt)) {
13854                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
13855                pw.println("  -a: include all available information for each process.");
13856                pw.println("  -d: include dalvik details when dumping process details.");
13857                pw.println("  -c: dump in a compact machine-parseable representation.");
13858                pw.println("  --oom: only show processes organized by oom adj.");
13859                pw.println("  --local: only collect details locally, don't call process.");
13860                pw.println("  --package: interpret process arg as package, dumping all");
13861                pw.println("             processes that have loaded that package.");
13862                pw.println("If [process] is specified it can be the name or ");
13863                pw.println("pid of a specific process to dump.");
13864                return;
13865            } else {
13866                pw.println("Unknown argument: " + opt + "; use -h for help");
13867            }
13868        }
13869
13870        final boolean isCheckinRequest = scanArgs(args, "--checkin");
13871        long uptime = SystemClock.uptimeMillis();
13872        long realtime = SystemClock.elapsedRealtime();
13873        final long[] tmpLong = new long[1];
13874
13875        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
13876        if (procs == null) {
13877            // No Java processes.  Maybe they want to print a native process.
13878            if (args != null && args.length > opti
13879                    && args[opti].charAt(0) != '-') {
13880                ArrayList<ProcessCpuTracker.Stats> nativeProcs
13881                        = new ArrayList<ProcessCpuTracker.Stats>();
13882                updateCpuStatsNow();
13883                int findPid = -1;
13884                try {
13885                    findPid = Integer.parseInt(args[opti]);
13886                } catch (NumberFormatException e) {
13887                }
13888                synchronized (mProcessCpuTracker) {
13889                    final int N = mProcessCpuTracker.countStats();
13890                    for (int i=0; i<N; i++) {
13891                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
13892                        if (st.pid == findPid || (st.baseName != null
13893                                && st.baseName.equals(args[opti]))) {
13894                            nativeProcs.add(st);
13895                        }
13896                    }
13897                }
13898                if (nativeProcs.size() > 0) {
13899                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
13900                            isCompact);
13901                    Debug.MemoryInfo mi = null;
13902                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
13903                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
13904                        final int pid = r.pid;
13905                        if (!isCheckinRequest && dumpDetails) {
13906                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
13907                        }
13908                        if (mi == null) {
13909                            mi = new Debug.MemoryInfo();
13910                        }
13911                        if (dumpDetails || (!brief && !oomOnly)) {
13912                            Debug.getMemoryInfo(pid, mi);
13913                        } else {
13914                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
13915                            mi.dalvikPrivateDirty = (int)tmpLong[0];
13916                        }
13917                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
13918                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
13919                        if (isCheckinRequest) {
13920                            pw.println();
13921                        }
13922                    }
13923                    return;
13924                }
13925            }
13926            pw.println("No process found for: " + args[opti]);
13927            return;
13928        }
13929
13930        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
13931            dumpDetails = true;
13932        }
13933
13934        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
13935
13936        String[] innerArgs = new String[args.length-opti];
13937        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
13938
13939        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
13940        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
13941        long nativePss = 0;
13942        long dalvikPss = 0;
13943        long otherPss = 0;
13944        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
13945
13946        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
13947        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
13948                new ArrayList[DUMP_MEM_OOM_LABEL.length];
13949
13950        long totalPss = 0;
13951        long cachedPss = 0;
13952
13953        Debug.MemoryInfo mi = null;
13954        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13955            final ProcessRecord r = procs.get(i);
13956            final IApplicationThread thread;
13957            final int pid;
13958            final int oomAdj;
13959            final boolean hasActivities;
13960            synchronized (this) {
13961                thread = r.thread;
13962                pid = r.pid;
13963                oomAdj = r.getSetAdjWithServices();
13964                hasActivities = r.activities.size() > 0;
13965            }
13966            if (thread != null) {
13967                if (!isCheckinRequest && dumpDetails) {
13968                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
13969                }
13970                if (mi == null) {
13971                    mi = new Debug.MemoryInfo();
13972                }
13973                if (dumpDetails || (!brief && !oomOnly)) {
13974                    Debug.getMemoryInfo(pid, mi);
13975                } else {
13976                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
13977                    mi.dalvikPrivateDirty = (int)tmpLong[0];
13978                }
13979                if (dumpDetails) {
13980                    if (localOnly) {
13981                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
13982                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
13983                        if (isCheckinRequest) {
13984                            pw.println();
13985                        }
13986                    } else {
13987                        try {
13988                            pw.flush();
13989                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
13990                                    dumpDalvik, innerArgs);
13991                        } catch (RemoteException e) {
13992                            if (!isCheckinRequest) {
13993                                pw.println("Got RemoteException!");
13994                                pw.flush();
13995                            }
13996                        }
13997                    }
13998                }
13999
14000                final long myTotalPss = mi.getTotalPss();
14001                final long myTotalUss = mi.getTotalUss();
14002
14003                synchronized (this) {
14004                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
14005                        // Record this for posterity if the process has been stable.
14006                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
14007                    }
14008                }
14009
14010                if (!isCheckinRequest && mi != null) {
14011                    totalPss += myTotalPss;
14012                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
14013                            (hasActivities ? " / activities)" : ")"),
14014                            r.processName, myTotalPss, pid, hasActivities);
14015                    procMems.add(pssItem);
14016                    procMemsMap.put(pid, pssItem);
14017
14018                    nativePss += mi.nativePss;
14019                    dalvikPss += mi.dalvikPss;
14020                    otherPss += mi.otherPss;
14021                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14022                        long mem = mi.getOtherPss(j);
14023                        miscPss[j] += mem;
14024                        otherPss -= mem;
14025                    }
14026
14027                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
14028                        cachedPss += myTotalPss;
14029                    }
14030
14031                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
14032                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
14033                                || oomIndex == (oomPss.length-1)) {
14034                            oomPss[oomIndex] += myTotalPss;
14035                            if (oomProcs[oomIndex] == null) {
14036                                oomProcs[oomIndex] = new ArrayList<MemItem>();
14037                            }
14038                            oomProcs[oomIndex].add(pssItem);
14039                            break;
14040                        }
14041                    }
14042                }
14043            }
14044        }
14045
14046        long nativeProcTotalPss = 0;
14047
14048        if (!isCheckinRequest && procs.size() > 1 && !packages) {
14049            // If we are showing aggregations, also look for native processes to
14050            // include so that our aggregations are more accurate.
14051            updateCpuStatsNow();
14052            synchronized (mProcessCpuTracker) {
14053                final int N = mProcessCpuTracker.countStats();
14054                for (int i=0; i<N; i++) {
14055                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14056                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
14057                        if (mi == null) {
14058                            mi = new Debug.MemoryInfo();
14059                        }
14060                        if (!brief && !oomOnly) {
14061                            Debug.getMemoryInfo(st.pid, mi);
14062                        } else {
14063                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
14064                            mi.nativePrivateDirty = (int)tmpLong[0];
14065                        }
14066
14067                        final long myTotalPss = mi.getTotalPss();
14068                        totalPss += myTotalPss;
14069                        nativeProcTotalPss += myTotalPss;
14070
14071                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
14072                                st.name, myTotalPss, st.pid, false);
14073                        procMems.add(pssItem);
14074
14075                        nativePss += mi.nativePss;
14076                        dalvikPss += mi.dalvikPss;
14077                        otherPss += mi.otherPss;
14078                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14079                            long mem = mi.getOtherPss(j);
14080                            miscPss[j] += mem;
14081                            otherPss -= mem;
14082                        }
14083                        oomPss[0] += myTotalPss;
14084                        if (oomProcs[0] == null) {
14085                            oomProcs[0] = new ArrayList<MemItem>();
14086                        }
14087                        oomProcs[0].add(pssItem);
14088                    }
14089                }
14090            }
14091
14092            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
14093
14094            catMems.add(new MemItem("Native", "Native", nativePss, -1));
14095            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
14096            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
14097            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14098                String label = Debug.MemoryInfo.getOtherLabel(j);
14099                catMems.add(new MemItem(label, label, miscPss[j], j));
14100            }
14101
14102            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
14103            for (int j=0; j<oomPss.length; j++) {
14104                if (oomPss[j] != 0) {
14105                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
14106                            : DUMP_MEM_OOM_LABEL[j];
14107                    MemItem item = new MemItem(label, label, oomPss[j],
14108                            DUMP_MEM_OOM_ADJ[j]);
14109                    item.subitems = oomProcs[j];
14110                    oomMems.add(item);
14111                }
14112            }
14113
14114            if (!brief && !oomOnly && !isCompact) {
14115                pw.println();
14116                pw.println("Total PSS by process:");
14117                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
14118                pw.println();
14119            }
14120            if (!isCompact) {
14121                pw.println("Total PSS by OOM adjustment:");
14122            }
14123            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
14124            if (!brief && !oomOnly) {
14125                PrintWriter out = categoryPw != null ? categoryPw : pw;
14126                if (!isCompact) {
14127                    out.println();
14128                    out.println("Total PSS by category:");
14129                }
14130                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
14131            }
14132            if (!isCompact) {
14133                pw.println();
14134            }
14135            MemInfoReader memInfo = new MemInfoReader();
14136            memInfo.readMemInfo();
14137            if (nativeProcTotalPss > 0) {
14138                synchronized (this) {
14139                    mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
14140                            memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
14141                            memInfo.getKernelUsedSizeKb(), nativeProcTotalPss);
14142                }
14143            }
14144            if (!brief) {
14145                if (!isCompact) {
14146                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
14147                    pw.print(" kB (status ");
14148                    switch (mLastMemoryLevel) {
14149                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
14150                            pw.println("normal)");
14151                            break;
14152                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
14153                            pw.println("moderate)");
14154                            break;
14155                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
14156                            pw.println("low)");
14157                            break;
14158                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
14159                            pw.println("critical)");
14160                            break;
14161                        default:
14162                            pw.print(mLastMemoryLevel);
14163                            pw.println(")");
14164                            break;
14165                    }
14166                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
14167                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
14168                            pw.print(cachedPss); pw.print(" cached pss + ");
14169                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached kernel + ");
14170                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
14171                } else {
14172                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
14173                    pw.print(cachedPss + memInfo.getCachedSizeKb()
14174                            + memInfo.getFreeSizeKb()); pw.print(",");
14175                    pw.println(totalPss - cachedPss);
14176                }
14177            }
14178            if (!isCompact) {
14179                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
14180                        + memInfo.getKernelUsedSizeKb()); pw.print(" kB (");
14181                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
14182                        pw.print(memInfo.getKernelUsedSizeKb()); pw.print(" kernel)\n");
14183                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
14184                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
14185                        - memInfo.getKernelUsedSizeKb()); pw.println(" kB");
14186            }
14187            if (!brief) {
14188                if (memInfo.getZramTotalSizeKb() != 0) {
14189                    if (!isCompact) {
14190                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
14191                                pw.print(" kB physical used for ");
14192                                pw.print(memInfo.getSwapTotalSizeKb()
14193                                        - memInfo.getSwapFreeSizeKb());
14194                                pw.print(" kB in swap (");
14195                                pw.print(memInfo.getSwapTotalSizeKb());
14196                                pw.println(" kB total swap)");
14197                    } else {
14198                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
14199                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
14200                                pw.println(memInfo.getSwapFreeSizeKb());
14201                    }
14202                }
14203                final long[] ksm = getKsmInfo();
14204                if (!isCompact) {
14205                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
14206                            || ksm[KSM_VOLATILE] != 0) {
14207                        pw.print("      KSM: "); pw.print(ksm[KSM_SHARING]);
14208                                pw.print(" kB saved from shared ");
14209                                pw.print(ksm[KSM_SHARED]); pw.println(" kB");
14210                        pw.print("           "); pw.print(ksm[KSM_UNSHARED]);
14211                                pw.print(" kB unshared; ");
14212                                pw.print(ksm[KSM_VOLATILE]); pw.println(" kB volatile");
14213                    }
14214                    pw.print("   Tuning: ");
14215                    pw.print(ActivityManager.staticGetMemoryClass());
14216                    pw.print(" (large ");
14217                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14218                    pw.print("), oom ");
14219                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14220                    pw.print(" kB");
14221                    pw.print(", restore limit ");
14222                    pw.print(mProcessList.getCachedRestoreThresholdKb());
14223                    pw.print(" kB");
14224                    if (ActivityManager.isLowRamDeviceStatic()) {
14225                        pw.print(" (low-ram)");
14226                    }
14227                    if (ActivityManager.isHighEndGfx()) {
14228                        pw.print(" (high-end-gfx)");
14229                    }
14230                    pw.println();
14231                } else {
14232                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
14233                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
14234                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
14235                    pw.print("tuning,");
14236                    pw.print(ActivityManager.staticGetMemoryClass());
14237                    pw.print(',');
14238                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14239                    pw.print(',');
14240                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14241                    if (ActivityManager.isLowRamDeviceStatic()) {
14242                        pw.print(",low-ram");
14243                    }
14244                    if (ActivityManager.isHighEndGfx()) {
14245                        pw.print(",high-end-gfx");
14246                    }
14247                    pw.println();
14248                }
14249            }
14250        }
14251    }
14252
14253    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
14254            String name) {
14255        sb.append("  ");
14256        sb.append(ProcessList.makeOomAdjString(oomAdj));
14257        sb.append(' ');
14258        sb.append(ProcessList.makeProcStateString(procState));
14259        sb.append(' ');
14260        ProcessList.appendRamKb(sb, pss);
14261        sb.append(" kB: ");
14262        sb.append(name);
14263    }
14264
14265    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
14266        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.name);
14267        sb.append(" (");
14268        sb.append(mi.pid);
14269        sb.append(") ");
14270        sb.append(mi.adjType);
14271        sb.append('\n');
14272        if (mi.adjReason != null) {
14273            sb.append("                      ");
14274            sb.append(mi.adjReason);
14275            sb.append('\n');
14276        }
14277    }
14278
14279    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
14280        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
14281        for (int i=0, N=memInfos.size(); i<N; i++) {
14282            ProcessMemInfo mi = memInfos.get(i);
14283            infoMap.put(mi.pid, mi);
14284        }
14285        updateCpuStatsNow();
14286        synchronized (mProcessCpuTracker) {
14287            final int N = mProcessCpuTracker.countStats();
14288            for (int i=0; i<N; i++) {
14289                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14290                if (st.vsize > 0) {
14291                    long pss = Debug.getPss(st.pid, null);
14292                    if (pss > 0) {
14293                        if (infoMap.indexOfKey(st.pid) < 0) {
14294                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
14295                                    ProcessList.NATIVE_ADJ, -1, "native", null);
14296                            mi.pss = pss;
14297                            memInfos.add(mi);
14298                        }
14299                    }
14300                }
14301            }
14302        }
14303
14304        long totalPss = 0;
14305        for (int i=0, N=memInfos.size(); i<N; i++) {
14306            ProcessMemInfo mi = memInfos.get(i);
14307            if (mi.pss == 0) {
14308                mi.pss = Debug.getPss(mi.pid, null);
14309            }
14310            totalPss += mi.pss;
14311        }
14312        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
14313            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
14314                if (lhs.oomAdj != rhs.oomAdj) {
14315                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
14316                }
14317                if (lhs.pss != rhs.pss) {
14318                    return lhs.pss < rhs.pss ? 1 : -1;
14319                }
14320                return 0;
14321            }
14322        });
14323
14324        StringBuilder tag = new StringBuilder(128);
14325        StringBuilder stack = new StringBuilder(128);
14326        tag.append("Low on memory -- ");
14327        appendMemBucket(tag, totalPss, "total", false);
14328        appendMemBucket(stack, totalPss, "total", true);
14329
14330        StringBuilder fullNativeBuilder = new StringBuilder(1024);
14331        StringBuilder shortNativeBuilder = new StringBuilder(1024);
14332        StringBuilder fullJavaBuilder = new StringBuilder(1024);
14333
14334        boolean firstLine = true;
14335        int lastOomAdj = Integer.MIN_VALUE;
14336        long extraNativeRam = 0;
14337        long cachedPss = 0;
14338        for (int i=0, N=memInfos.size(); i<N; i++) {
14339            ProcessMemInfo mi = memInfos.get(i);
14340
14341            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
14342                cachedPss += mi.pss;
14343            }
14344
14345            if (mi.oomAdj != ProcessList.NATIVE_ADJ
14346                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
14347                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
14348                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
14349                if (lastOomAdj != mi.oomAdj) {
14350                    lastOomAdj = mi.oomAdj;
14351                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14352                        tag.append(" / ");
14353                    }
14354                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
14355                        if (firstLine) {
14356                            stack.append(":");
14357                            firstLine = false;
14358                        }
14359                        stack.append("\n\t at ");
14360                    } else {
14361                        stack.append("$");
14362                    }
14363                } else {
14364                    tag.append(" ");
14365                    stack.append("$");
14366                }
14367                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14368                    appendMemBucket(tag, mi.pss, mi.name, false);
14369                }
14370                appendMemBucket(stack, mi.pss, mi.name, true);
14371                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
14372                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
14373                    stack.append("(");
14374                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
14375                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
14376                            stack.append(DUMP_MEM_OOM_LABEL[k]);
14377                            stack.append(":");
14378                            stack.append(DUMP_MEM_OOM_ADJ[k]);
14379                        }
14380                    }
14381                    stack.append(")");
14382                }
14383            }
14384
14385            appendMemInfo(fullNativeBuilder, mi);
14386            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
14387                // The short form only has native processes that are >= 1MB.
14388                if (mi.pss >= 1000) {
14389                    appendMemInfo(shortNativeBuilder, mi);
14390                } else {
14391                    extraNativeRam += mi.pss;
14392                }
14393            } else {
14394                // Short form has all other details, but if we have collected RAM
14395                // from smaller native processes let's dump a summary of that.
14396                if (extraNativeRam > 0) {
14397                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
14398                            -1, extraNativeRam, "(Other native)");
14399                    shortNativeBuilder.append('\n');
14400                    extraNativeRam = 0;
14401                }
14402                appendMemInfo(fullJavaBuilder, mi);
14403            }
14404        }
14405
14406        fullJavaBuilder.append("           ");
14407        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
14408        fullJavaBuilder.append(" kB: TOTAL\n");
14409
14410        MemInfoReader memInfo = new MemInfoReader();
14411        memInfo.readMemInfo();
14412        final long[] infos = memInfo.getRawInfo();
14413
14414        StringBuilder memInfoBuilder = new StringBuilder(1024);
14415        Debug.getMemInfo(infos);
14416        memInfoBuilder.append("  MemInfo: ");
14417        memInfoBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
14418        memInfoBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
14419        memInfoBuilder.append(infos[Debug.MEMINFO_VM_ALLOC_USED]).append(" kB vm alloc, ");
14420        memInfoBuilder.append(infos[Debug.MEMINFO_PAGE_TABLES]).append(" kB page tables ");
14421        memInfoBuilder.append(infos[Debug.MEMINFO_KERNEL_STACK]).append(" kB kernel stack\n");
14422        memInfoBuilder.append("           ");
14423        memInfoBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
14424        memInfoBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
14425        memInfoBuilder.append(infos[Debug.MEMINFO_MAPPED]).append(" kB mapped, ");
14426        memInfoBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
14427        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
14428            memInfoBuilder.append("  ZRAM: ");
14429            memInfoBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
14430            memInfoBuilder.append(" kB RAM, ");
14431            memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
14432            memInfoBuilder.append(" kB swap total, ");
14433            memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
14434            memInfoBuilder.append(" kB swap free\n");
14435        }
14436        final long[] ksm = getKsmInfo();
14437        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
14438                || ksm[KSM_VOLATILE] != 0) {
14439            memInfoBuilder.append("  KSM: "); memInfoBuilder.append(ksm[KSM_SHARING]);
14440            memInfoBuilder.append(" kB saved from shared ");
14441            memInfoBuilder.append(ksm[KSM_SHARED]); memInfoBuilder.append(" kB\n");
14442            memInfoBuilder.append("       "); memInfoBuilder.append(ksm[KSM_UNSHARED]);
14443            memInfoBuilder.append(" kB unshared; ");
14444            memInfoBuilder.append(ksm[KSM_VOLATILE]); memInfoBuilder.append(" kB volatile\n");
14445        }
14446        memInfoBuilder.append("  Free RAM: ");
14447        memInfoBuilder.append(cachedPss + memInfo.getCachedSizeKb()
14448                + memInfo.getFreeSizeKb());
14449        memInfoBuilder.append(" kB\n");
14450        memInfoBuilder.append("  Used RAM: ");
14451        memInfoBuilder.append(totalPss - cachedPss + memInfo.getKernelUsedSizeKb());
14452        memInfoBuilder.append(" kB\n");
14453        memInfoBuilder.append("  Lost RAM: ");
14454        memInfoBuilder.append(memInfo.getTotalSizeKb()
14455                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
14456                - memInfo.getKernelUsedSizeKb());
14457        memInfoBuilder.append(" kB\n");
14458        Slog.i(TAG, "Low on memory:");
14459        Slog.i(TAG, shortNativeBuilder.toString());
14460        Slog.i(TAG, fullJavaBuilder.toString());
14461        Slog.i(TAG, memInfoBuilder.toString());
14462
14463        StringBuilder dropBuilder = new StringBuilder(1024);
14464        /*
14465        StringWriter oomSw = new StringWriter();
14466        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
14467        StringWriter catSw = new StringWriter();
14468        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
14469        String[] emptyArgs = new String[] { };
14470        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
14471        oomPw.flush();
14472        String oomString = oomSw.toString();
14473        */
14474        dropBuilder.append("Low on memory:");
14475        dropBuilder.append(stack);
14476        dropBuilder.append('\n');
14477        dropBuilder.append(fullNativeBuilder);
14478        dropBuilder.append(fullJavaBuilder);
14479        dropBuilder.append('\n');
14480        dropBuilder.append(memInfoBuilder);
14481        dropBuilder.append('\n');
14482        /*
14483        dropBuilder.append(oomString);
14484        dropBuilder.append('\n');
14485        */
14486        StringWriter catSw = new StringWriter();
14487        synchronized (ActivityManagerService.this) {
14488            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
14489            String[] emptyArgs = new String[] { };
14490            catPw.println();
14491            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
14492            catPw.println();
14493            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
14494                    false, false, null);
14495            catPw.println();
14496            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
14497            catPw.flush();
14498        }
14499        dropBuilder.append(catSw.toString());
14500        addErrorToDropBox("lowmem", null, "system_server", null,
14501                null, tag.toString(), dropBuilder.toString(), null, null);
14502        //Slog.i(TAG, "Sent to dropbox:");
14503        //Slog.i(TAG, dropBuilder.toString());
14504        synchronized (ActivityManagerService.this) {
14505            long now = SystemClock.uptimeMillis();
14506            if (mLastMemUsageReportTime < now) {
14507                mLastMemUsageReportTime = now;
14508            }
14509        }
14510    }
14511
14512    /**
14513     * Searches array of arguments for the specified string
14514     * @param args array of argument strings
14515     * @param value value to search for
14516     * @return true if the value is contained in the array
14517     */
14518    private static boolean scanArgs(String[] args, String value) {
14519        if (args != null) {
14520            for (String arg : args) {
14521                if (value.equals(arg)) {
14522                    return true;
14523                }
14524            }
14525        }
14526        return false;
14527    }
14528
14529    private final boolean removeDyingProviderLocked(ProcessRecord proc,
14530            ContentProviderRecord cpr, boolean always) {
14531        final boolean inLaunching = mLaunchingProviders.contains(cpr);
14532
14533        if (!inLaunching || always) {
14534            synchronized (cpr) {
14535                cpr.launchingApp = null;
14536                cpr.notifyAll();
14537            }
14538            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
14539            String names[] = cpr.info.authority.split(";");
14540            for (int j = 0; j < names.length; j++) {
14541                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
14542            }
14543        }
14544
14545        for (int i=0; i<cpr.connections.size(); i++) {
14546            ContentProviderConnection conn = cpr.connections.get(i);
14547            if (conn.waiting) {
14548                // If this connection is waiting for the provider, then we don't
14549                // need to mess with its process unless we are always removing
14550                // or for some reason the provider is not currently launching.
14551                if (inLaunching && !always) {
14552                    continue;
14553                }
14554            }
14555            ProcessRecord capp = conn.client;
14556            conn.dead = true;
14557            if (conn.stableCount > 0) {
14558                if (!capp.persistent && capp.thread != null
14559                        && capp.pid != 0
14560                        && capp.pid != MY_PID) {
14561                    capp.kill("depends on provider "
14562                            + cpr.name.flattenToShortString()
14563                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
14564                }
14565            } else if (capp.thread != null && conn.provider.provider != null) {
14566                try {
14567                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
14568                } catch (RemoteException e) {
14569                }
14570                // In the protocol here, we don't expect the client to correctly
14571                // clean up this connection, we'll just remove it.
14572                cpr.connections.remove(i);
14573                conn.client.conProviders.remove(conn);
14574            }
14575        }
14576
14577        if (inLaunching && always) {
14578            mLaunchingProviders.remove(cpr);
14579        }
14580        return inLaunching;
14581    }
14582
14583    /**
14584     * Main code for cleaning up a process when it has gone away.  This is
14585     * called both as a result of the process dying, or directly when stopping
14586     * a process when running in single process mode.
14587     *
14588     * @return Returns true if the given process has been restarted, so the
14589     * app that was passed in must remain on the process lists.
14590     */
14591    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
14592            boolean restarting, boolean allowRestart, int index) {
14593        if (index >= 0) {
14594            removeLruProcessLocked(app);
14595            ProcessList.remove(app.pid);
14596        }
14597
14598        mProcessesToGc.remove(app);
14599        mPendingPssProcesses.remove(app);
14600
14601        // Dismiss any open dialogs.
14602        if (app.crashDialog != null && !app.forceCrashReport) {
14603            app.crashDialog.dismiss();
14604            app.crashDialog = null;
14605        }
14606        if (app.anrDialog != null) {
14607            app.anrDialog.dismiss();
14608            app.anrDialog = null;
14609        }
14610        if (app.waitDialog != null) {
14611            app.waitDialog.dismiss();
14612            app.waitDialog = null;
14613        }
14614
14615        app.crashing = false;
14616        app.notResponding = false;
14617
14618        app.resetPackageList(mProcessStats);
14619        app.unlinkDeathRecipient();
14620        app.makeInactive(mProcessStats);
14621        app.waitingToKill = null;
14622        app.forcingToForeground = null;
14623        updateProcessForegroundLocked(app, false, false);
14624        app.foregroundActivities = false;
14625        app.hasShownUi = false;
14626        app.treatLikeActivity = false;
14627        app.hasAboveClient = false;
14628        app.hasClientActivities = false;
14629
14630        mServices.killServicesLocked(app, allowRestart);
14631
14632        boolean restart = false;
14633
14634        // Remove published content providers.
14635        for (int i=app.pubProviders.size()-1; i>=0; i--) {
14636            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
14637            final boolean always = app.bad || !allowRestart;
14638            if (removeDyingProviderLocked(app, cpr, always) || always) {
14639                // We left the provider in the launching list, need to
14640                // restart it.
14641                restart = true;
14642            }
14643
14644            cpr.provider = null;
14645            cpr.proc = null;
14646        }
14647        app.pubProviders.clear();
14648
14649        // Take care of any launching providers waiting for this process.
14650        if (checkAppInLaunchingProvidersLocked(app, false)) {
14651            restart = true;
14652        }
14653
14654        // Unregister from connected content providers.
14655        if (!app.conProviders.isEmpty()) {
14656            for (int i=0; i<app.conProviders.size(); i++) {
14657                ContentProviderConnection conn = app.conProviders.get(i);
14658                conn.provider.connections.remove(conn);
14659            }
14660            app.conProviders.clear();
14661        }
14662
14663        // At this point there may be remaining entries in mLaunchingProviders
14664        // where we were the only one waiting, so they are no longer of use.
14665        // Look for these and clean up if found.
14666        // XXX Commented out for now.  Trying to figure out a way to reproduce
14667        // the actual situation to identify what is actually going on.
14668        if (false) {
14669            for (int i=0; i<mLaunchingProviders.size(); i++) {
14670                ContentProviderRecord cpr = (ContentProviderRecord)
14671                        mLaunchingProviders.get(i);
14672                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
14673                    synchronized (cpr) {
14674                        cpr.launchingApp = null;
14675                        cpr.notifyAll();
14676                    }
14677                }
14678            }
14679        }
14680
14681        skipCurrentReceiverLocked(app);
14682
14683        // Unregister any receivers.
14684        for (int i=app.receivers.size()-1; i>=0; i--) {
14685            removeReceiverLocked(app.receivers.valueAt(i));
14686        }
14687        app.receivers.clear();
14688
14689        // If the app is undergoing backup, tell the backup manager about it
14690        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
14691            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
14692                    + mBackupTarget.appInfo + " died during backup");
14693            try {
14694                IBackupManager bm = IBackupManager.Stub.asInterface(
14695                        ServiceManager.getService(Context.BACKUP_SERVICE));
14696                bm.agentDisconnected(app.info.packageName);
14697            } catch (RemoteException e) {
14698                // can't happen; backup manager is local
14699            }
14700        }
14701
14702        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
14703            ProcessChangeItem item = mPendingProcessChanges.get(i);
14704            if (item.pid == app.pid) {
14705                mPendingProcessChanges.remove(i);
14706                mAvailProcessChanges.add(item);
14707            }
14708        }
14709        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
14710
14711        // If the caller is restarting this app, then leave it in its
14712        // current lists and let the caller take care of it.
14713        if (restarting) {
14714            return false;
14715        }
14716
14717        if (!app.persistent || app.isolated) {
14718            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
14719                    "Removing non-persistent process during cleanup: " + app);
14720            mProcessNames.remove(app.processName, app.uid);
14721            mIsolatedProcesses.remove(app.uid);
14722            if (mHeavyWeightProcess == app) {
14723                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
14724                        mHeavyWeightProcess.userId, 0));
14725                mHeavyWeightProcess = null;
14726            }
14727        } else if (!app.removed) {
14728            // This app is persistent, so we need to keep its record around.
14729            // If it is not already on the pending app list, add it there
14730            // and start a new process for it.
14731            if (mPersistentStartingProcesses.indexOf(app) < 0) {
14732                mPersistentStartingProcesses.add(app);
14733                restart = true;
14734            }
14735        }
14736        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
14737                "Clean-up removing on hold: " + app);
14738        mProcessesOnHold.remove(app);
14739
14740        if (app == mHomeProcess) {
14741            mHomeProcess = null;
14742        }
14743        if (app == mPreviousProcess) {
14744            mPreviousProcess = null;
14745        }
14746
14747        if (restart && !app.isolated) {
14748            // We have components that still need to be running in the
14749            // process, so re-launch it.
14750            if (index < 0) {
14751                ProcessList.remove(app.pid);
14752            }
14753            mProcessNames.put(app.processName, app.uid, app);
14754            startProcessLocked(app, "restart", app.processName);
14755            return true;
14756        } else if (app.pid > 0 && app.pid != MY_PID) {
14757            // Goodbye!
14758            boolean removed;
14759            synchronized (mPidsSelfLocked) {
14760                mPidsSelfLocked.remove(app.pid);
14761                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
14762            }
14763            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
14764            if (app.isolated) {
14765                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
14766            }
14767            app.setPid(0);
14768        }
14769        return false;
14770    }
14771
14772    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
14773        // Look through the content providers we are waiting to have launched,
14774        // and if any run in this process then either schedule a restart of
14775        // the process or kill the client waiting for it if this process has
14776        // gone bad.
14777        int NL = mLaunchingProviders.size();
14778        boolean restart = false;
14779        for (int i=0; i<NL; i++) {
14780            ContentProviderRecord cpr = mLaunchingProviders.get(i);
14781            if (cpr.launchingApp == app) {
14782                if (!alwaysBad && !app.bad) {
14783                    restart = true;
14784                } else {
14785                    removeDyingProviderLocked(app, cpr, true);
14786                    // cpr should have been removed from mLaunchingProviders
14787                    NL = mLaunchingProviders.size();
14788                    i--;
14789                }
14790            }
14791        }
14792        return restart;
14793    }
14794
14795    // =========================================================
14796    // SERVICES
14797    // =========================================================
14798
14799    @Override
14800    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
14801            int flags) {
14802        enforceNotIsolatedCaller("getServices");
14803        synchronized (this) {
14804            return mServices.getRunningServiceInfoLocked(maxNum, flags);
14805        }
14806    }
14807
14808    @Override
14809    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
14810        enforceNotIsolatedCaller("getRunningServiceControlPanel");
14811        synchronized (this) {
14812            return mServices.getRunningServiceControlPanelLocked(name);
14813        }
14814    }
14815
14816    @Override
14817    public ComponentName startService(IApplicationThread caller, Intent service,
14818            String resolvedType, int userId) {
14819        enforceNotIsolatedCaller("startService");
14820        // Refuse possible leaked file descriptors
14821        if (service != null && service.hasFileDescriptors() == true) {
14822            throw new IllegalArgumentException("File descriptors passed in Intent");
14823        }
14824
14825        if (DEBUG_SERVICE)
14826            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
14827        synchronized(this) {
14828            final int callingPid = Binder.getCallingPid();
14829            final int callingUid = Binder.getCallingUid();
14830            final long origId = Binder.clearCallingIdentity();
14831            ComponentName res = mServices.startServiceLocked(caller, service,
14832                    resolvedType, callingPid, callingUid, userId);
14833            Binder.restoreCallingIdentity(origId);
14834            return res;
14835        }
14836    }
14837
14838    ComponentName startServiceInPackage(int uid,
14839            Intent service, String resolvedType, int userId) {
14840        synchronized(this) {
14841            if (DEBUG_SERVICE)
14842                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
14843            final long origId = Binder.clearCallingIdentity();
14844            ComponentName res = mServices.startServiceLocked(null, service,
14845                    resolvedType, -1, uid, userId);
14846            Binder.restoreCallingIdentity(origId);
14847            return res;
14848        }
14849    }
14850
14851    @Override
14852    public int stopService(IApplicationThread caller, Intent service,
14853            String resolvedType, int userId) {
14854        enforceNotIsolatedCaller("stopService");
14855        // Refuse possible leaked file descriptors
14856        if (service != null && service.hasFileDescriptors() == true) {
14857            throw new IllegalArgumentException("File descriptors passed in Intent");
14858        }
14859
14860        synchronized(this) {
14861            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
14862        }
14863    }
14864
14865    @Override
14866    public IBinder peekService(Intent service, String resolvedType) {
14867        enforceNotIsolatedCaller("peekService");
14868        // Refuse possible leaked file descriptors
14869        if (service != null && service.hasFileDescriptors() == true) {
14870            throw new IllegalArgumentException("File descriptors passed in Intent");
14871        }
14872        synchronized(this) {
14873            return mServices.peekServiceLocked(service, resolvedType);
14874        }
14875    }
14876
14877    @Override
14878    public boolean stopServiceToken(ComponentName className, IBinder token,
14879            int startId) {
14880        synchronized(this) {
14881            return mServices.stopServiceTokenLocked(className, token, startId);
14882        }
14883    }
14884
14885    @Override
14886    public void setServiceForeground(ComponentName className, IBinder token,
14887            int id, Notification notification, boolean removeNotification) {
14888        synchronized(this) {
14889            mServices.setServiceForegroundLocked(className, token, id, notification,
14890                    removeNotification);
14891        }
14892    }
14893
14894    @Override
14895    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14896            boolean requireFull, String name, String callerPackage) {
14897        return handleIncomingUser(callingPid, callingUid, userId, allowAll,
14898                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
14899    }
14900
14901    int unsafeConvertIncomingUser(int userId) {
14902        return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
14903                ? mCurrentUserId : userId;
14904    }
14905
14906    int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14907            int allowMode, String name, String callerPackage) {
14908        final int callingUserId = UserHandle.getUserId(callingUid);
14909        if (callingUserId == userId) {
14910            return userId;
14911        }
14912
14913        // Note that we may be accessing mCurrentUserId outside of a lock...
14914        // shouldn't be a big deal, if this is being called outside
14915        // of a locked context there is intrinsically a race with
14916        // the value the caller will receive and someone else changing it.
14917        // We assume that USER_CURRENT_OR_SELF will use the current user; later
14918        // we will switch to the calling user if access to the current user fails.
14919        int targetUserId = unsafeConvertIncomingUser(userId);
14920
14921        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
14922            final boolean allow;
14923            if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
14924                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
14925                // If the caller has this permission, they always pass go.  And collect $200.
14926                allow = true;
14927            } else if (allowMode == ALLOW_FULL_ONLY) {
14928                // We require full access, sucks to be you.
14929                allow = false;
14930            } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
14931                    callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
14932                // If the caller does not have either permission, they are always doomed.
14933                allow = false;
14934            } else if (allowMode == ALLOW_NON_FULL) {
14935                // We are blanket allowing non-full access, you lucky caller!
14936                allow = true;
14937            } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
14938                // We may or may not allow this depending on whether the two users are
14939                // in the same profile.
14940                synchronized (mUserProfileGroupIdsSelfLocked) {
14941                    int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
14942                            UserInfo.NO_PROFILE_GROUP_ID);
14943                    int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
14944                            UserInfo.NO_PROFILE_GROUP_ID);
14945                    allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
14946                            && callingProfile == targetProfile;
14947                }
14948            } else {
14949                throw new IllegalArgumentException("Unknown mode: " + allowMode);
14950            }
14951            if (!allow) {
14952                if (userId == UserHandle.USER_CURRENT_OR_SELF) {
14953                    // In this case, they would like to just execute as their
14954                    // owner user instead of failing.
14955                    targetUserId = callingUserId;
14956                } else {
14957                    StringBuilder builder = new StringBuilder(128);
14958                    builder.append("Permission Denial: ");
14959                    builder.append(name);
14960                    if (callerPackage != null) {
14961                        builder.append(" from ");
14962                        builder.append(callerPackage);
14963                    }
14964                    builder.append(" asks to run as user ");
14965                    builder.append(userId);
14966                    builder.append(" but is calling from user ");
14967                    builder.append(UserHandle.getUserId(callingUid));
14968                    builder.append("; this requires ");
14969                    builder.append(INTERACT_ACROSS_USERS_FULL);
14970                    if (allowMode != ALLOW_FULL_ONLY) {
14971                        builder.append(" or ");
14972                        builder.append(INTERACT_ACROSS_USERS);
14973                    }
14974                    String msg = builder.toString();
14975                    Slog.w(TAG, msg);
14976                    throw new SecurityException(msg);
14977                }
14978            }
14979        }
14980        if (!allowAll && targetUserId < 0) {
14981            throw new IllegalArgumentException(
14982                    "Call does not support special user #" + targetUserId);
14983        }
14984        // Check shell permission
14985        if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) {
14986            if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES,
14987                    targetUserId)) {
14988                throw new SecurityException("Shell does not have permission to access user "
14989                        + targetUserId + "\n " + Debug.getCallers(3));
14990            }
14991        }
14992        return targetUserId;
14993    }
14994
14995    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
14996            String className, int flags) {
14997        boolean result = false;
14998        // For apps that don't have pre-defined UIDs, check for permission
14999        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
15000            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
15001                if (ActivityManager.checkUidPermission(
15002                        INTERACT_ACROSS_USERS,
15003                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
15004                    ComponentName comp = new ComponentName(aInfo.packageName, className);
15005                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
15006                            + " requests FLAG_SINGLE_USER, but app does not hold "
15007                            + INTERACT_ACROSS_USERS;
15008                    Slog.w(TAG, msg);
15009                    throw new SecurityException(msg);
15010                }
15011                // Permission passed
15012                result = true;
15013            }
15014        } else if ("system".equals(componentProcessName)) {
15015            result = true;
15016        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
15017            // Phone app and persistent apps are allowed to export singleuser providers.
15018            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
15019                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
15020        }
15021        if (DEBUG_MU) {
15022            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
15023                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
15024        }
15025        return result;
15026    }
15027
15028    /**
15029     * Checks to see if the caller is in the same app as the singleton
15030     * component, or the component is in a special app. It allows special apps
15031     * to export singleton components but prevents exporting singleton
15032     * components for regular apps.
15033     */
15034    boolean isValidSingletonCall(int callingUid, int componentUid) {
15035        int componentAppId = UserHandle.getAppId(componentUid);
15036        return UserHandle.isSameApp(callingUid, componentUid)
15037                || componentAppId == Process.SYSTEM_UID
15038                || componentAppId == Process.PHONE_UID
15039                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
15040                        == PackageManager.PERMISSION_GRANTED;
15041    }
15042
15043    public int bindService(IApplicationThread caller, IBinder token,
15044            Intent service, String resolvedType,
15045            IServiceConnection connection, int flags, int userId) {
15046        enforceNotIsolatedCaller("bindService");
15047
15048        // Refuse possible leaked file descriptors
15049        if (service != null && service.hasFileDescriptors() == true) {
15050            throw new IllegalArgumentException("File descriptors passed in Intent");
15051        }
15052
15053        synchronized(this) {
15054            return mServices.bindServiceLocked(caller, token, service, resolvedType,
15055                    connection, flags, userId);
15056        }
15057    }
15058
15059    public boolean unbindService(IServiceConnection connection) {
15060        synchronized (this) {
15061            return mServices.unbindServiceLocked(connection);
15062        }
15063    }
15064
15065    public void publishService(IBinder token, Intent intent, IBinder service) {
15066        // Refuse possible leaked file descriptors
15067        if (intent != null && intent.hasFileDescriptors() == true) {
15068            throw new IllegalArgumentException("File descriptors passed in Intent");
15069        }
15070
15071        synchronized(this) {
15072            if (!(token instanceof ServiceRecord)) {
15073                throw new IllegalArgumentException("Invalid service token");
15074            }
15075            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
15076        }
15077    }
15078
15079    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
15080        // Refuse possible leaked file descriptors
15081        if (intent != null && intent.hasFileDescriptors() == true) {
15082            throw new IllegalArgumentException("File descriptors passed in Intent");
15083        }
15084
15085        synchronized(this) {
15086            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
15087        }
15088    }
15089
15090    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
15091        synchronized(this) {
15092            if (!(token instanceof ServiceRecord)) {
15093                throw new IllegalArgumentException("Invalid service token");
15094            }
15095            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
15096        }
15097    }
15098
15099    // =========================================================
15100    // BACKUP AND RESTORE
15101    // =========================================================
15102
15103    // Cause the target app to be launched if necessary and its backup agent
15104    // instantiated.  The backup agent will invoke backupAgentCreated() on the
15105    // activity manager to announce its creation.
15106    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
15107        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
15108        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
15109
15110        synchronized(this) {
15111            // !!! TODO: currently no check here that we're already bound
15112            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
15113            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15114            synchronized (stats) {
15115                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
15116            }
15117
15118            // Backup agent is now in use, its package can't be stopped.
15119            try {
15120                AppGlobals.getPackageManager().setPackageStoppedState(
15121                        app.packageName, false, UserHandle.getUserId(app.uid));
15122            } catch (RemoteException e) {
15123            } catch (IllegalArgumentException e) {
15124                Slog.w(TAG, "Failed trying to unstop package "
15125                        + app.packageName + ": " + e);
15126            }
15127
15128            BackupRecord r = new BackupRecord(ss, app, backupMode);
15129            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
15130                    ? new ComponentName(app.packageName, app.backupAgentName)
15131                    : new ComponentName("android", "FullBackupAgent");
15132            // startProcessLocked() returns existing proc's record if it's already running
15133            ProcessRecord proc = startProcessLocked(app.processName, app,
15134                    false, 0, "backup", hostingName, false, false, false);
15135            if (proc == null) {
15136                Slog.e(TAG, "Unable to start backup agent process " + r);
15137                return false;
15138            }
15139
15140            r.app = proc;
15141            mBackupTarget = r;
15142            mBackupAppName = app.packageName;
15143
15144            // Try not to kill the process during backup
15145            updateOomAdjLocked(proc);
15146
15147            // If the process is already attached, schedule the creation of the backup agent now.
15148            // If it is not yet live, this will be done when it attaches to the framework.
15149            if (proc.thread != null) {
15150                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
15151                try {
15152                    proc.thread.scheduleCreateBackupAgent(app,
15153                            compatibilityInfoForPackageLocked(app), backupMode);
15154                } catch (RemoteException e) {
15155                    // Will time out on the backup manager side
15156                }
15157            } else {
15158                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
15159            }
15160            // Invariants: at this point, the target app process exists and the application
15161            // is either already running or in the process of coming up.  mBackupTarget and
15162            // mBackupAppName describe the app, so that when it binds back to the AM we
15163            // know that it's scheduled for a backup-agent operation.
15164        }
15165
15166        return true;
15167    }
15168
15169    @Override
15170    public void clearPendingBackup() {
15171        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
15172        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
15173
15174        synchronized (this) {
15175            mBackupTarget = null;
15176            mBackupAppName = null;
15177        }
15178    }
15179
15180    // A backup agent has just come up
15181    public void backupAgentCreated(String agentPackageName, IBinder agent) {
15182        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
15183                + " = " + agent);
15184
15185        synchronized(this) {
15186            if (!agentPackageName.equals(mBackupAppName)) {
15187                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
15188                return;
15189            }
15190        }
15191
15192        long oldIdent = Binder.clearCallingIdentity();
15193        try {
15194            IBackupManager bm = IBackupManager.Stub.asInterface(
15195                    ServiceManager.getService(Context.BACKUP_SERVICE));
15196            bm.agentConnected(agentPackageName, agent);
15197        } catch (RemoteException e) {
15198            // can't happen; the backup manager service is local
15199        } catch (Exception e) {
15200            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
15201            e.printStackTrace();
15202        } finally {
15203            Binder.restoreCallingIdentity(oldIdent);
15204        }
15205    }
15206
15207    // done with this agent
15208    public void unbindBackupAgent(ApplicationInfo appInfo) {
15209        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
15210        if (appInfo == null) {
15211            Slog.w(TAG, "unbind backup agent for null app");
15212            return;
15213        }
15214
15215        synchronized(this) {
15216            try {
15217                if (mBackupAppName == null) {
15218                    Slog.w(TAG, "Unbinding backup agent with no active backup");
15219                    return;
15220                }
15221
15222                if (!mBackupAppName.equals(appInfo.packageName)) {
15223                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
15224                    return;
15225                }
15226
15227                // Not backing this app up any more; reset its OOM adjustment
15228                final ProcessRecord proc = mBackupTarget.app;
15229                updateOomAdjLocked(proc);
15230
15231                // If the app crashed during backup, 'thread' will be null here
15232                if (proc.thread != null) {
15233                    try {
15234                        proc.thread.scheduleDestroyBackupAgent(appInfo,
15235                                compatibilityInfoForPackageLocked(appInfo));
15236                    } catch (Exception e) {
15237                        Slog.e(TAG, "Exception when unbinding backup agent:");
15238                        e.printStackTrace();
15239                    }
15240                }
15241            } finally {
15242                mBackupTarget = null;
15243                mBackupAppName = null;
15244            }
15245        }
15246    }
15247    // =========================================================
15248    // BROADCASTS
15249    // =========================================================
15250
15251    private final List getStickiesLocked(String action, IntentFilter filter,
15252            List cur, int userId) {
15253        final ContentResolver resolver = mContext.getContentResolver();
15254        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15255        if (stickies == null) {
15256            return cur;
15257        }
15258        final ArrayList<Intent> list = stickies.get(action);
15259        if (list == null) {
15260            return cur;
15261        }
15262        int N = list.size();
15263        for (int i=0; i<N; i++) {
15264            Intent intent = list.get(i);
15265            if (filter.match(resolver, intent, true, TAG) >= 0) {
15266                if (cur == null) {
15267                    cur = new ArrayList<Intent>();
15268                }
15269                cur.add(intent);
15270            }
15271        }
15272        return cur;
15273    }
15274
15275    boolean isPendingBroadcastProcessLocked(int pid) {
15276        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
15277                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
15278    }
15279
15280    void skipPendingBroadcastLocked(int pid) {
15281            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
15282            for (BroadcastQueue queue : mBroadcastQueues) {
15283                queue.skipPendingBroadcastLocked(pid);
15284            }
15285    }
15286
15287    // The app just attached; send any pending broadcasts that it should receive
15288    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
15289        boolean didSomething = false;
15290        for (BroadcastQueue queue : mBroadcastQueues) {
15291            didSomething |= queue.sendPendingBroadcastsLocked(app);
15292        }
15293        return didSomething;
15294    }
15295
15296    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
15297            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
15298        enforceNotIsolatedCaller("registerReceiver");
15299        int callingUid;
15300        int callingPid;
15301        synchronized(this) {
15302            ProcessRecord callerApp = null;
15303            if (caller != null) {
15304                callerApp = getRecordForAppLocked(caller);
15305                if (callerApp == null) {
15306                    throw new SecurityException(
15307                            "Unable to find app for caller " + caller
15308                            + " (pid=" + Binder.getCallingPid()
15309                            + ") when registering receiver " + receiver);
15310                }
15311                if (callerApp.info.uid != Process.SYSTEM_UID &&
15312                        !callerApp.pkgList.containsKey(callerPackage) &&
15313                        !"android".equals(callerPackage)) {
15314                    throw new SecurityException("Given caller package " + callerPackage
15315                            + " is not running in process " + callerApp);
15316                }
15317                callingUid = callerApp.info.uid;
15318                callingPid = callerApp.pid;
15319            } else {
15320                callerPackage = null;
15321                callingUid = Binder.getCallingUid();
15322                callingPid = Binder.getCallingPid();
15323            }
15324
15325            userId = this.handleIncomingUser(callingPid, callingUid, userId,
15326                    true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
15327
15328            List allSticky = null;
15329
15330            // Look for any matching sticky broadcasts...
15331            Iterator actions = filter.actionsIterator();
15332            if (actions != null) {
15333                while (actions.hasNext()) {
15334                    String action = (String)actions.next();
15335                    allSticky = getStickiesLocked(action, filter, allSticky,
15336                            UserHandle.USER_ALL);
15337                    allSticky = getStickiesLocked(action, filter, allSticky,
15338                            UserHandle.getUserId(callingUid));
15339                }
15340            } else {
15341                allSticky = getStickiesLocked(null, filter, allSticky,
15342                        UserHandle.USER_ALL);
15343                allSticky = getStickiesLocked(null, filter, allSticky,
15344                        UserHandle.getUserId(callingUid));
15345            }
15346
15347            // The first sticky in the list is returned directly back to
15348            // the client.
15349            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
15350
15351            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
15352                    + ": " + sticky);
15353
15354            if (receiver == null) {
15355                return sticky;
15356            }
15357
15358            ReceiverList rl
15359                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
15360            if (rl == null) {
15361                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
15362                        userId, receiver);
15363                if (rl.app != null) {
15364                    rl.app.receivers.add(rl);
15365                } else {
15366                    try {
15367                        receiver.asBinder().linkToDeath(rl, 0);
15368                    } catch (RemoteException e) {
15369                        return sticky;
15370                    }
15371                    rl.linkedToDeath = true;
15372                }
15373                mRegisteredReceivers.put(receiver.asBinder(), rl);
15374            } else if (rl.uid != callingUid) {
15375                throw new IllegalArgumentException(
15376                        "Receiver requested to register for uid " + callingUid
15377                        + " was previously registered for uid " + rl.uid);
15378            } else if (rl.pid != callingPid) {
15379                throw new IllegalArgumentException(
15380                        "Receiver requested to register for pid " + callingPid
15381                        + " was previously registered for pid " + rl.pid);
15382            } else if (rl.userId != userId) {
15383                throw new IllegalArgumentException(
15384                        "Receiver requested to register for user " + userId
15385                        + " was previously registered for user " + rl.userId);
15386            }
15387            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
15388                    permission, callingUid, userId);
15389            rl.add(bf);
15390            if (!bf.debugCheck()) {
15391                Slog.w(TAG, "==> For Dynamic broadast");
15392            }
15393            mReceiverResolver.addFilter(bf);
15394
15395            // Enqueue broadcasts for all existing stickies that match
15396            // this filter.
15397            if (allSticky != null) {
15398                ArrayList receivers = new ArrayList();
15399                receivers.add(bf);
15400
15401                int N = allSticky.size();
15402                for (int i=0; i<N; i++) {
15403                    Intent intent = (Intent)allSticky.get(i);
15404                    BroadcastQueue queue = broadcastQueueForIntent(intent);
15405                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
15406                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
15407                            null, null, false, true, true, -1);
15408                    queue.enqueueParallelBroadcastLocked(r);
15409                    queue.scheduleBroadcastsLocked();
15410                }
15411            }
15412
15413            return sticky;
15414        }
15415    }
15416
15417    public void unregisterReceiver(IIntentReceiver receiver) {
15418        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
15419
15420        final long origId = Binder.clearCallingIdentity();
15421        try {
15422            boolean doTrim = false;
15423
15424            synchronized(this) {
15425                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
15426                if (rl != null) {
15427                    if (rl.curBroadcast != null) {
15428                        BroadcastRecord r = rl.curBroadcast;
15429                        final boolean doNext = finishReceiverLocked(
15430                                receiver.asBinder(), r.resultCode, r.resultData,
15431                                r.resultExtras, r.resultAbort);
15432                        if (doNext) {
15433                            doTrim = true;
15434                            r.queue.processNextBroadcast(false);
15435                        }
15436                    }
15437
15438                    if (rl.app != null) {
15439                        rl.app.receivers.remove(rl);
15440                    }
15441                    removeReceiverLocked(rl);
15442                    if (rl.linkedToDeath) {
15443                        rl.linkedToDeath = false;
15444                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
15445                    }
15446                }
15447            }
15448
15449            // If we actually concluded any broadcasts, we might now be able
15450            // to trim the recipients' apps from our working set
15451            if (doTrim) {
15452                trimApplications();
15453                return;
15454            }
15455
15456        } finally {
15457            Binder.restoreCallingIdentity(origId);
15458        }
15459    }
15460
15461    void removeReceiverLocked(ReceiverList rl) {
15462        mRegisteredReceivers.remove(rl.receiver.asBinder());
15463        int N = rl.size();
15464        for (int i=0; i<N; i++) {
15465            mReceiverResolver.removeFilter(rl.get(i));
15466        }
15467    }
15468
15469    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
15470        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
15471            ProcessRecord r = mLruProcesses.get(i);
15472            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
15473                try {
15474                    r.thread.dispatchPackageBroadcast(cmd, packages);
15475                } catch (RemoteException ex) {
15476                }
15477            }
15478        }
15479    }
15480
15481    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
15482            int callingUid, int[] users) {
15483        List<ResolveInfo> receivers = null;
15484        try {
15485            HashSet<ComponentName> singleUserReceivers = null;
15486            boolean scannedFirstReceivers = false;
15487            for (int user : users) {
15488                // Skip users that have Shell restrictions
15489                if (callingUid == Process.SHELL_UID
15490                        && getUserManagerLocked().hasUserRestriction(
15491                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)) {
15492                    continue;
15493                }
15494                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
15495                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
15496                if (user != 0 && newReceivers != null) {
15497                    // If this is not the primary user, we need to check for
15498                    // any receivers that should be filtered out.
15499                    for (int i=0; i<newReceivers.size(); i++) {
15500                        ResolveInfo ri = newReceivers.get(i);
15501                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
15502                            newReceivers.remove(i);
15503                            i--;
15504                        }
15505                    }
15506                }
15507                if (newReceivers != null && newReceivers.size() == 0) {
15508                    newReceivers = null;
15509                }
15510                if (receivers == null) {
15511                    receivers = newReceivers;
15512                } else if (newReceivers != null) {
15513                    // We need to concatenate the additional receivers
15514                    // found with what we have do far.  This would be easy,
15515                    // but we also need to de-dup any receivers that are
15516                    // singleUser.
15517                    if (!scannedFirstReceivers) {
15518                        // Collect any single user receivers we had already retrieved.
15519                        scannedFirstReceivers = true;
15520                        for (int i=0; i<receivers.size(); i++) {
15521                            ResolveInfo ri = receivers.get(i);
15522                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15523                                ComponentName cn = new ComponentName(
15524                                        ri.activityInfo.packageName, ri.activityInfo.name);
15525                                if (singleUserReceivers == null) {
15526                                    singleUserReceivers = new HashSet<ComponentName>();
15527                                }
15528                                singleUserReceivers.add(cn);
15529                            }
15530                        }
15531                    }
15532                    // Add the new results to the existing results, tracking
15533                    // and de-dupping single user receivers.
15534                    for (int i=0; i<newReceivers.size(); i++) {
15535                        ResolveInfo ri = newReceivers.get(i);
15536                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15537                            ComponentName cn = new ComponentName(
15538                                    ri.activityInfo.packageName, ri.activityInfo.name);
15539                            if (singleUserReceivers == null) {
15540                                singleUserReceivers = new HashSet<ComponentName>();
15541                            }
15542                            if (!singleUserReceivers.contains(cn)) {
15543                                singleUserReceivers.add(cn);
15544                                receivers.add(ri);
15545                            }
15546                        } else {
15547                            receivers.add(ri);
15548                        }
15549                    }
15550                }
15551            }
15552        } catch (RemoteException ex) {
15553            // pm is in same process, this will never happen.
15554        }
15555        return receivers;
15556    }
15557
15558    private final int broadcastIntentLocked(ProcessRecord callerApp,
15559            String callerPackage, Intent intent, String resolvedType,
15560            IIntentReceiver resultTo, int resultCode, String resultData,
15561            Bundle map, String requiredPermission, int appOp,
15562            boolean ordered, boolean sticky, int callingPid, int callingUid,
15563            int userId) {
15564        intent = new Intent(intent);
15565
15566        // By default broadcasts do not go to stopped apps.
15567        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
15568
15569        if (DEBUG_BROADCAST_LIGHT) Slog.v(
15570            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
15571            + " ordered=" + ordered + " userid=" + userId);
15572        if ((resultTo != null) && !ordered) {
15573            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
15574        }
15575
15576        userId = handleIncomingUser(callingPid, callingUid, userId,
15577                true, ALLOW_NON_FULL, "broadcast", callerPackage);
15578
15579        // Make sure that the user who is receiving this broadcast is started.
15580        // If not, we will just skip it.
15581
15582        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
15583            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
15584                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
15585                Slog.w(TAG, "Skipping broadcast of " + intent
15586                        + ": user " + userId + " is stopped");
15587                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
15588            }
15589        }
15590
15591        /*
15592         * Prevent non-system code (defined here to be non-persistent
15593         * processes) from sending protected broadcasts.
15594         */
15595        int callingAppId = UserHandle.getAppId(callingUid);
15596        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
15597            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
15598            || callingAppId == Process.NFC_UID || callingUid == 0) {
15599            // Always okay.
15600        } else if (callerApp == null || !callerApp.persistent) {
15601            try {
15602                if (AppGlobals.getPackageManager().isProtectedBroadcast(
15603                        intent.getAction())) {
15604                    String msg = "Permission Denial: not allowed to send broadcast "
15605                            + intent.getAction() + " from pid="
15606                            + callingPid + ", uid=" + callingUid;
15607                    Slog.w(TAG, msg);
15608                    throw new SecurityException(msg);
15609                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
15610                    // Special case for compatibility: we don't want apps to send this,
15611                    // but historically it has not been protected and apps may be using it
15612                    // to poke their own app widget.  So, instead of making it protected,
15613                    // just limit it to the caller.
15614                    if (callerApp == null) {
15615                        String msg = "Permission Denial: not allowed to send broadcast "
15616                                + intent.getAction() + " from unknown caller.";
15617                        Slog.w(TAG, msg);
15618                        throw new SecurityException(msg);
15619                    } else if (intent.getComponent() != null) {
15620                        // They are good enough to send to an explicit component...  verify
15621                        // it is being sent to the calling app.
15622                        if (!intent.getComponent().getPackageName().equals(
15623                                callerApp.info.packageName)) {
15624                            String msg = "Permission Denial: not allowed to send broadcast "
15625                                    + intent.getAction() + " to "
15626                                    + intent.getComponent().getPackageName() + " from "
15627                                    + callerApp.info.packageName;
15628                            Slog.w(TAG, msg);
15629                            throw new SecurityException(msg);
15630                        }
15631                    } else {
15632                        // Limit broadcast to their own package.
15633                        intent.setPackage(callerApp.info.packageName);
15634                    }
15635                }
15636            } catch (RemoteException e) {
15637                Slog.w(TAG, "Remote exception", e);
15638                return ActivityManager.BROADCAST_SUCCESS;
15639            }
15640        }
15641
15642        final String action = intent.getAction();
15643        if (action != null) {
15644            switch (action) {
15645                case Intent.ACTION_UID_REMOVED:
15646                case Intent.ACTION_PACKAGE_REMOVED:
15647                case Intent.ACTION_PACKAGE_CHANGED:
15648                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
15649                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
15650                    // Handle special intents: if this broadcast is from the package
15651                    // manager about a package being removed, we need to remove all of
15652                    // its activities from the history stack.
15653                    if (checkComponentPermission(
15654                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
15655                            callingPid, callingUid, -1, true)
15656                            != PackageManager.PERMISSION_GRANTED) {
15657                        String msg = "Permission Denial: " + intent.getAction()
15658                                + " broadcast from " + callerPackage + " (pid=" + callingPid
15659                                + ", uid=" + callingUid + ")"
15660                                + " requires "
15661                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
15662                        Slog.w(TAG, msg);
15663                        throw new SecurityException(msg);
15664                    }
15665                    switch (action) {
15666                        case Intent.ACTION_UID_REMOVED:
15667                            final Bundle intentExtras = intent.getExtras();
15668                            final int uid = intentExtras != null
15669                                    ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
15670                            if (uid >= 0) {
15671                                BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
15672                                synchronized (bs) {
15673                                    bs.removeUidStatsLocked(uid);
15674                                }
15675                                mAppOpsService.uidRemoved(uid);
15676                            }
15677                            break;
15678                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
15679                            // If resources are unavailable just force stop all those packages
15680                            // and flush the attribute cache as well.
15681                            String list[] =
15682                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15683                            if (list != null && list.length > 0) {
15684                                for (int i = 0; i < list.length; i++) {
15685                                    forceStopPackageLocked(list[i], -1, false, true, true,
15686                                            false, false, userId, "storage unmount");
15687                                }
15688                                cleanupRecentTasksLocked(UserHandle.USER_ALL);
15689                                sendPackageBroadcastLocked(
15690                                        IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
15691                                        userId);
15692                            }
15693                            break;
15694                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
15695                            cleanupRecentTasksLocked(UserHandle.USER_ALL);
15696                            break;
15697                        case Intent.ACTION_PACKAGE_REMOVED:
15698                        case Intent.ACTION_PACKAGE_CHANGED:
15699                            Uri data = intent.getData();
15700                            String ssp;
15701                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
15702                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
15703                                boolean fullUninstall = removed &&
15704                                        !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
15705                                if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
15706                                    forceStopPackageLocked(ssp, UserHandle.getAppId(
15707                                            intent.getIntExtra(Intent.EXTRA_UID, -1)),
15708                                            false, true, true, false, fullUninstall, userId,
15709                                            removed ? "pkg removed" : "pkg changed");
15710                                }
15711                                if (removed) {
15712                                    sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
15713                                            new String[] {ssp}, userId);
15714                                    if (fullUninstall) {
15715                                        mAppOpsService.packageRemoved(
15716                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
15717
15718                                        // Remove all permissions granted from/to this package
15719                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
15720
15721                                        removeTasksByPackageNameLocked(ssp, userId);
15722                                    }
15723                                } else {
15724                                    removeTasksByRemovedPackageComponentsLocked(ssp, userId);
15725                                }
15726                            }
15727                            break;
15728                    }
15729                    break;
15730                case Intent.ACTION_PACKAGE_ADDED:
15731                    // Special case for adding a package: by default turn on compatibility mode.
15732                    Uri data = intent.getData();
15733                    String ssp;
15734                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
15735                        final boolean replacing =
15736                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
15737                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
15738
15739                        if (replacing) {
15740                            removeTasksByRemovedPackageComponentsLocked(ssp, userId);
15741                        }
15742                    }
15743                    break;
15744                case Intent.ACTION_TIMEZONE_CHANGED:
15745                    // If this is the time zone changed action, queue up a message that will reset
15746                    // the timezone of all currently running processes. This message will get
15747                    // queued up before the broadcast happens.
15748                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
15749                    break;
15750                case Intent.ACTION_TIME_CHANGED:
15751                    // If the user set the time, let all running processes know.
15752                    final int is24Hour =
15753                            intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
15754                                    : 0;
15755                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
15756                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15757                    synchronized (stats) {
15758                        stats.noteCurrentTimeChangedLocked();
15759                    }
15760                    break;
15761                case Intent.ACTION_CLEAR_DNS_CACHE:
15762                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
15763                    break;
15764                case Proxy.PROXY_CHANGE_ACTION:
15765                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
15766                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
15767                    break;
15768            }
15769        }
15770
15771        // Add to the sticky list if requested.
15772        if (sticky) {
15773            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
15774                    callingPid, callingUid)
15775                    != PackageManager.PERMISSION_GRANTED) {
15776                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
15777                        + callingPid + ", uid=" + callingUid
15778                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
15779                Slog.w(TAG, msg);
15780                throw new SecurityException(msg);
15781            }
15782            if (requiredPermission != null) {
15783                Slog.w(TAG, "Can't broadcast sticky intent " + intent
15784                        + " and enforce permission " + requiredPermission);
15785                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
15786            }
15787            if (intent.getComponent() != null) {
15788                throw new SecurityException(
15789                        "Sticky broadcasts can't target a specific component");
15790            }
15791            // We use userId directly here, since the "all" target is maintained
15792            // as a separate set of sticky broadcasts.
15793            if (userId != UserHandle.USER_ALL) {
15794                // But first, if this is not a broadcast to all users, then
15795                // make sure it doesn't conflict with an existing broadcast to
15796                // all users.
15797                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
15798                        UserHandle.USER_ALL);
15799                if (stickies != null) {
15800                    ArrayList<Intent> list = stickies.get(intent.getAction());
15801                    if (list != null) {
15802                        int N = list.size();
15803                        int i;
15804                        for (i=0; i<N; i++) {
15805                            if (intent.filterEquals(list.get(i))) {
15806                                throw new IllegalArgumentException(
15807                                        "Sticky broadcast " + intent + " for user "
15808                                        + userId + " conflicts with existing global broadcast");
15809                            }
15810                        }
15811                    }
15812                }
15813            }
15814            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15815            if (stickies == null) {
15816                stickies = new ArrayMap<String, ArrayList<Intent>>();
15817                mStickyBroadcasts.put(userId, stickies);
15818            }
15819            ArrayList<Intent> list = stickies.get(intent.getAction());
15820            if (list == null) {
15821                list = new ArrayList<Intent>();
15822                stickies.put(intent.getAction(), list);
15823            }
15824            int N = list.size();
15825            int i;
15826            for (i=0; i<N; i++) {
15827                if (intent.filterEquals(list.get(i))) {
15828                    // This sticky already exists, replace it.
15829                    list.set(i, new Intent(intent));
15830                    break;
15831                }
15832            }
15833            if (i >= N) {
15834                list.add(new Intent(intent));
15835            }
15836        }
15837
15838        int[] users;
15839        if (userId == UserHandle.USER_ALL) {
15840            // Caller wants broadcast to go to all started users.
15841            users = mStartedUserArray;
15842        } else {
15843            // Caller wants broadcast to go to one specific user.
15844            users = new int[] {userId};
15845        }
15846
15847        // Figure out who all will receive this broadcast.
15848        List receivers = null;
15849        List<BroadcastFilter> registeredReceivers = null;
15850        // Need to resolve the intent to interested receivers...
15851        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
15852                 == 0) {
15853            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
15854        }
15855        if (intent.getComponent() == null) {
15856            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
15857                // Query one target user at a time, excluding shell-restricted users
15858                UserManagerService ums = getUserManagerLocked();
15859                for (int i = 0; i < users.length; i++) {
15860                    if (ums.hasUserRestriction(
15861                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
15862                        continue;
15863                    }
15864                    List<BroadcastFilter> registeredReceiversForUser =
15865                            mReceiverResolver.queryIntent(intent,
15866                                    resolvedType, false, users[i]);
15867                    if (registeredReceivers == null) {
15868                        registeredReceivers = registeredReceiversForUser;
15869                    } else if (registeredReceiversForUser != null) {
15870                        registeredReceivers.addAll(registeredReceiversForUser);
15871                    }
15872                }
15873            } else {
15874                registeredReceivers = mReceiverResolver.queryIntent(intent,
15875                        resolvedType, false, userId);
15876            }
15877        }
15878
15879        final boolean replacePending =
15880                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
15881
15882        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
15883                + " replacePending=" + replacePending);
15884
15885        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
15886        if (!ordered && NR > 0) {
15887            // If we are not serializing this broadcast, then send the
15888            // registered receivers separately so they don't wait for the
15889            // components to be launched.
15890            final BroadcastQueue queue = broadcastQueueForIntent(intent);
15891            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
15892                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
15893                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
15894                    ordered, sticky, false, userId);
15895            if (DEBUG_BROADCAST) Slog.v(
15896                    TAG, "Enqueueing parallel broadcast " + r);
15897            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
15898            if (!replaced) {
15899                queue.enqueueParallelBroadcastLocked(r);
15900                queue.scheduleBroadcastsLocked();
15901            }
15902            registeredReceivers = null;
15903            NR = 0;
15904        }
15905
15906        // Merge into one list.
15907        int ir = 0;
15908        if (receivers != null) {
15909            // A special case for PACKAGE_ADDED: do not allow the package
15910            // being added to see this broadcast.  This prevents them from
15911            // using this as a back door to get run as soon as they are
15912            // installed.  Maybe in the future we want to have a special install
15913            // broadcast or such for apps, but we'd like to deliberately make
15914            // this decision.
15915            String skipPackages[] = null;
15916            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
15917                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
15918                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
15919                Uri data = intent.getData();
15920                if (data != null) {
15921                    String pkgName = data.getSchemeSpecificPart();
15922                    if (pkgName != null) {
15923                        skipPackages = new String[] { pkgName };
15924                    }
15925                }
15926            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
15927                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15928            }
15929            if (skipPackages != null && (skipPackages.length > 0)) {
15930                for (String skipPackage : skipPackages) {
15931                    if (skipPackage != null) {
15932                        int NT = receivers.size();
15933                        for (int it=0; it<NT; it++) {
15934                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
15935                            if (curt.activityInfo.packageName.equals(skipPackage)) {
15936                                receivers.remove(it);
15937                                it--;
15938                                NT--;
15939                            }
15940                        }
15941                    }
15942                }
15943            }
15944
15945            int NT = receivers != null ? receivers.size() : 0;
15946            int it = 0;
15947            ResolveInfo curt = null;
15948            BroadcastFilter curr = null;
15949            while (it < NT && ir < NR) {
15950                if (curt == null) {
15951                    curt = (ResolveInfo)receivers.get(it);
15952                }
15953                if (curr == null) {
15954                    curr = registeredReceivers.get(ir);
15955                }
15956                if (curr.getPriority() >= curt.priority) {
15957                    // Insert this broadcast record into the final list.
15958                    receivers.add(it, curr);
15959                    ir++;
15960                    curr = null;
15961                    it++;
15962                    NT++;
15963                } else {
15964                    // Skip to the next ResolveInfo in the final list.
15965                    it++;
15966                    curt = null;
15967                }
15968            }
15969        }
15970        while (ir < NR) {
15971            if (receivers == null) {
15972                receivers = new ArrayList();
15973            }
15974            receivers.add(registeredReceivers.get(ir));
15975            ir++;
15976        }
15977
15978        if ((receivers != null && receivers.size() > 0)
15979                || resultTo != null) {
15980            BroadcastQueue queue = broadcastQueueForIntent(intent);
15981            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
15982                    callerPackage, callingPid, callingUid, resolvedType,
15983                    requiredPermission, appOp, receivers, resultTo, resultCode,
15984                    resultData, map, ordered, sticky, false, userId);
15985            if (DEBUG_BROADCAST) Slog.v(
15986                    TAG, "Enqueueing ordered broadcast " + r
15987                    + ": prev had " + queue.mOrderedBroadcasts.size());
15988            if (DEBUG_BROADCAST) {
15989                int seq = r.intent.getIntExtra("seq", -1);
15990                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
15991            }
15992            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
15993            if (!replaced) {
15994                queue.enqueueOrderedBroadcastLocked(r);
15995                queue.scheduleBroadcastsLocked();
15996            }
15997        }
15998
15999        return ActivityManager.BROADCAST_SUCCESS;
16000    }
16001
16002    final Intent verifyBroadcastLocked(Intent intent) {
16003        // Refuse possible leaked file descriptors
16004        if (intent != null && intent.hasFileDescriptors() == true) {
16005            throw new IllegalArgumentException("File descriptors passed in Intent");
16006        }
16007
16008        int flags = intent.getFlags();
16009
16010        if (!mProcessesReady) {
16011            // if the caller really truly claims to know what they're doing, go
16012            // ahead and allow the broadcast without launching any receivers
16013            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
16014                intent = new Intent(intent);
16015                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16016            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
16017                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
16018                        + " before boot completion");
16019                throw new IllegalStateException("Cannot broadcast before boot completed");
16020            }
16021        }
16022
16023        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
16024            throw new IllegalArgumentException(
16025                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
16026        }
16027
16028        return intent;
16029    }
16030
16031    public final int broadcastIntent(IApplicationThread caller,
16032            Intent intent, String resolvedType, IIntentReceiver resultTo,
16033            int resultCode, String resultData, Bundle map,
16034            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
16035        enforceNotIsolatedCaller("broadcastIntent");
16036        synchronized(this) {
16037            intent = verifyBroadcastLocked(intent);
16038
16039            final ProcessRecord callerApp = getRecordForAppLocked(caller);
16040            final int callingPid = Binder.getCallingPid();
16041            final int callingUid = Binder.getCallingUid();
16042            final long origId = Binder.clearCallingIdentity();
16043            int res = broadcastIntentLocked(callerApp,
16044                    callerApp != null ? callerApp.info.packageName : null,
16045                    intent, resolvedType, resultTo,
16046                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
16047                    callingPid, callingUid, userId);
16048            Binder.restoreCallingIdentity(origId);
16049            return res;
16050        }
16051    }
16052
16053    int broadcastIntentInPackage(String packageName, int uid,
16054            Intent intent, String resolvedType, IIntentReceiver resultTo,
16055            int resultCode, String resultData, Bundle map,
16056            String requiredPermission, boolean serialized, boolean sticky, int userId) {
16057        synchronized(this) {
16058            intent = verifyBroadcastLocked(intent);
16059
16060            final long origId = Binder.clearCallingIdentity();
16061            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
16062                    resultTo, resultCode, resultData, map, requiredPermission,
16063                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
16064            Binder.restoreCallingIdentity(origId);
16065            return res;
16066        }
16067    }
16068
16069    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
16070        // Refuse possible leaked file descriptors
16071        if (intent != null && intent.hasFileDescriptors() == true) {
16072            throw new IllegalArgumentException("File descriptors passed in Intent");
16073        }
16074
16075        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16076                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
16077
16078        synchronized(this) {
16079            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
16080                    != PackageManager.PERMISSION_GRANTED) {
16081                String msg = "Permission Denial: unbroadcastIntent() from pid="
16082                        + Binder.getCallingPid()
16083                        + ", uid=" + Binder.getCallingUid()
16084                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
16085                Slog.w(TAG, msg);
16086                throw new SecurityException(msg);
16087            }
16088            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
16089            if (stickies != null) {
16090                ArrayList<Intent> list = stickies.get(intent.getAction());
16091                if (list != null) {
16092                    int N = list.size();
16093                    int i;
16094                    for (i=0; i<N; i++) {
16095                        if (intent.filterEquals(list.get(i))) {
16096                            list.remove(i);
16097                            break;
16098                        }
16099                    }
16100                    if (list.size() <= 0) {
16101                        stickies.remove(intent.getAction());
16102                    }
16103                }
16104                if (stickies.size() <= 0) {
16105                    mStickyBroadcasts.remove(userId);
16106                }
16107            }
16108        }
16109    }
16110
16111    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
16112            String resultData, Bundle resultExtras, boolean resultAbort) {
16113        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
16114        if (r == null) {
16115            Slog.w(TAG, "finishReceiver called but not found on queue");
16116            return false;
16117        }
16118
16119        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
16120    }
16121
16122    void backgroundServicesFinishedLocked(int userId) {
16123        for (BroadcastQueue queue : mBroadcastQueues) {
16124            queue.backgroundServicesFinishedLocked(userId);
16125        }
16126    }
16127
16128    public void finishReceiver(IBinder who, int resultCode, String resultData,
16129            Bundle resultExtras, boolean resultAbort) {
16130        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
16131
16132        // Refuse possible leaked file descriptors
16133        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
16134            throw new IllegalArgumentException("File descriptors passed in Bundle");
16135        }
16136
16137        final long origId = Binder.clearCallingIdentity();
16138        try {
16139            boolean doNext = false;
16140            BroadcastRecord r;
16141
16142            synchronized(this) {
16143                r = broadcastRecordForReceiverLocked(who);
16144                if (r != null) {
16145                    doNext = r.queue.finishReceiverLocked(r, resultCode,
16146                        resultData, resultExtras, resultAbort, true);
16147                }
16148            }
16149
16150            if (doNext) {
16151                r.queue.processNextBroadcast(false);
16152            }
16153            trimApplications();
16154        } finally {
16155            Binder.restoreCallingIdentity(origId);
16156        }
16157    }
16158
16159    // =========================================================
16160    // INSTRUMENTATION
16161    // =========================================================
16162
16163    public boolean startInstrumentation(ComponentName className,
16164            String profileFile, int flags, Bundle arguments,
16165            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
16166            int userId, String abiOverride) {
16167        enforceNotIsolatedCaller("startInstrumentation");
16168        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16169                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
16170        // Refuse possible leaked file descriptors
16171        if (arguments != null && arguments.hasFileDescriptors()) {
16172            throw new IllegalArgumentException("File descriptors passed in Bundle");
16173        }
16174
16175        synchronized(this) {
16176            InstrumentationInfo ii = null;
16177            ApplicationInfo ai = null;
16178            try {
16179                ii = mContext.getPackageManager().getInstrumentationInfo(
16180                    className, STOCK_PM_FLAGS);
16181                ai = AppGlobals.getPackageManager().getApplicationInfo(
16182                        ii.targetPackage, STOCK_PM_FLAGS, userId);
16183            } catch (PackageManager.NameNotFoundException e) {
16184            } catch (RemoteException e) {
16185            }
16186            if (ii == null) {
16187                reportStartInstrumentationFailure(watcher, className,
16188                        "Unable to find instrumentation info for: " + className);
16189                return false;
16190            }
16191            if (ai == null) {
16192                reportStartInstrumentationFailure(watcher, className,
16193                        "Unable to find instrumentation target package: " + ii.targetPackage);
16194                return false;
16195            }
16196
16197            int match = mContext.getPackageManager().checkSignatures(
16198                    ii.targetPackage, ii.packageName);
16199            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
16200                String msg = "Permission Denial: starting instrumentation "
16201                        + className + " from pid="
16202                        + Binder.getCallingPid()
16203                        + ", uid=" + Binder.getCallingPid()
16204                        + " not allowed because package " + ii.packageName
16205                        + " does not have a signature matching the target "
16206                        + ii.targetPackage;
16207                reportStartInstrumentationFailure(watcher, className, msg);
16208                throw new SecurityException(msg);
16209            }
16210
16211            final long origId = Binder.clearCallingIdentity();
16212            // Instrumentation can kill and relaunch even persistent processes
16213            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
16214                    "start instr");
16215            ProcessRecord app = addAppLocked(ai, false, abiOverride);
16216            app.instrumentationClass = className;
16217            app.instrumentationInfo = ai;
16218            app.instrumentationProfileFile = profileFile;
16219            app.instrumentationArguments = arguments;
16220            app.instrumentationWatcher = watcher;
16221            app.instrumentationUiAutomationConnection = uiAutomationConnection;
16222            app.instrumentationResultClass = className;
16223            Binder.restoreCallingIdentity(origId);
16224        }
16225
16226        return true;
16227    }
16228
16229    /**
16230     * Report errors that occur while attempting to start Instrumentation.  Always writes the
16231     * error to the logs, but if somebody is watching, send the report there too.  This enables
16232     * the "am" command to report errors with more information.
16233     *
16234     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
16235     * @param cn The component name of the instrumentation.
16236     * @param report The error report.
16237     */
16238    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
16239            ComponentName cn, String report) {
16240        Slog.w(TAG, report);
16241        try {
16242            if (watcher != null) {
16243                Bundle results = new Bundle();
16244                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
16245                results.putString("Error", report);
16246                watcher.instrumentationStatus(cn, -1, results);
16247            }
16248        } catch (RemoteException e) {
16249            Slog.w(TAG, e);
16250        }
16251    }
16252
16253    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
16254        if (app.instrumentationWatcher != null) {
16255            try {
16256                // NOTE:  IInstrumentationWatcher *must* be oneway here
16257                app.instrumentationWatcher.instrumentationFinished(
16258                    app.instrumentationClass,
16259                    resultCode,
16260                    results);
16261            } catch (RemoteException e) {
16262            }
16263        }
16264        if (app.instrumentationUiAutomationConnection != null) {
16265            try {
16266                app.instrumentationUiAutomationConnection.shutdown();
16267            } catch (RemoteException re) {
16268                /* ignore */
16269            }
16270            // Only a UiAutomation can set this flag and now that
16271            // it is finished we make sure it is reset to its default.
16272            mUserIsMonkey = false;
16273        }
16274        app.instrumentationWatcher = null;
16275        app.instrumentationUiAutomationConnection = null;
16276        app.instrumentationClass = null;
16277        app.instrumentationInfo = null;
16278        app.instrumentationProfileFile = null;
16279        app.instrumentationArguments = null;
16280
16281        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
16282                "finished inst");
16283    }
16284
16285    public void finishInstrumentation(IApplicationThread target,
16286            int resultCode, Bundle results) {
16287        int userId = UserHandle.getCallingUserId();
16288        // Refuse possible leaked file descriptors
16289        if (results != null && results.hasFileDescriptors()) {
16290            throw new IllegalArgumentException("File descriptors passed in Intent");
16291        }
16292
16293        synchronized(this) {
16294            ProcessRecord app = getRecordForAppLocked(target);
16295            if (app == null) {
16296                Slog.w(TAG, "finishInstrumentation: no app for " + target);
16297                return;
16298            }
16299            final long origId = Binder.clearCallingIdentity();
16300            finishInstrumentationLocked(app, resultCode, results);
16301            Binder.restoreCallingIdentity(origId);
16302        }
16303    }
16304
16305    // =========================================================
16306    // CONFIGURATION
16307    // =========================================================
16308
16309    public ConfigurationInfo getDeviceConfigurationInfo() {
16310        ConfigurationInfo config = new ConfigurationInfo();
16311        synchronized (this) {
16312            config.reqTouchScreen = mConfiguration.touchscreen;
16313            config.reqKeyboardType = mConfiguration.keyboard;
16314            config.reqNavigation = mConfiguration.navigation;
16315            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
16316                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
16317                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
16318            }
16319            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
16320                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
16321                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
16322            }
16323            config.reqGlEsVersion = GL_ES_VERSION;
16324        }
16325        return config;
16326    }
16327
16328    ActivityStack getFocusedStack() {
16329        return mStackSupervisor.getFocusedStack();
16330    }
16331
16332    public Configuration getConfiguration() {
16333        Configuration ci;
16334        synchronized(this) {
16335            ci = new Configuration(mConfiguration);
16336        }
16337        return ci;
16338    }
16339
16340    public void updatePersistentConfiguration(Configuration values) {
16341        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16342                "updateConfiguration()");
16343        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
16344                "updateConfiguration()");
16345        if (values == null) {
16346            throw new NullPointerException("Configuration must not be null");
16347        }
16348
16349        synchronized(this) {
16350            final long origId = Binder.clearCallingIdentity();
16351            updateConfigurationLocked(values, null, true, false);
16352            Binder.restoreCallingIdentity(origId);
16353        }
16354    }
16355
16356    public void updateConfiguration(Configuration values) {
16357        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16358                "updateConfiguration()");
16359
16360        synchronized(this) {
16361            if (values == null && mWindowManager != null) {
16362                // sentinel: fetch the current configuration from the window manager
16363                values = mWindowManager.computeNewConfiguration();
16364            }
16365
16366            if (mWindowManager != null) {
16367                mProcessList.applyDisplaySize(mWindowManager);
16368            }
16369
16370            final long origId = Binder.clearCallingIdentity();
16371            if (values != null) {
16372                Settings.System.clearConfiguration(values);
16373            }
16374            updateConfigurationLocked(values, null, false, false);
16375            Binder.restoreCallingIdentity(origId);
16376        }
16377    }
16378
16379    /**
16380     * Do either or both things: (1) change the current configuration, and (2)
16381     * make sure the given activity is running with the (now) current
16382     * configuration.  Returns true if the activity has been left running, or
16383     * false if <var>starting</var> is being destroyed to match the new
16384     * configuration.
16385     * @param persistent TODO
16386     */
16387    boolean updateConfigurationLocked(Configuration values,
16388            ActivityRecord starting, boolean persistent, boolean initLocale) {
16389        int changes = 0;
16390
16391        if (values != null) {
16392            Configuration newConfig = new Configuration(mConfiguration);
16393            changes = newConfig.updateFrom(values);
16394            if (changes != 0) {
16395                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
16396                    Slog.i(TAG, "Updating configuration to: " + values);
16397                }
16398
16399                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
16400
16401                if (values.locale != null && !initLocale) {
16402                    saveLocaleLocked(values.locale,
16403                                     !values.locale.equals(mConfiguration.locale),
16404                                     values.userSetLocale);
16405                }
16406
16407                mConfigurationSeq++;
16408                if (mConfigurationSeq <= 0) {
16409                    mConfigurationSeq = 1;
16410                }
16411                newConfig.seq = mConfigurationSeq;
16412                mConfiguration = newConfig;
16413                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
16414                mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId);
16415                //mUsageStatsService.noteStartConfig(newConfig);
16416
16417                final Configuration configCopy = new Configuration(mConfiguration);
16418
16419                // TODO: If our config changes, should we auto dismiss any currently
16420                // showing dialogs?
16421                mShowDialogs = shouldShowDialogs(newConfig);
16422
16423                AttributeCache ac = AttributeCache.instance();
16424                if (ac != null) {
16425                    ac.updateConfiguration(configCopy);
16426                }
16427
16428                // Make sure all resources in our process are updated
16429                // right now, so that anyone who is going to retrieve
16430                // resource values after we return will be sure to get
16431                // the new ones.  This is especially important during
16432                // boot, where the first config change needs to guarantee
16433                // all resources have that config before following boot
16434                // code is executed.
16435                mSystemThread.applyConfigurationToResources(configCopy);
16436
16437                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
16438                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
16439                    msg.obj = new Configuration(configCopy);
16440                    mHandler.sendMessage(msg);
16441                }
16442
16443                for (int i=mLruProcesses.size()-1; i>=0; i--) {
16444                    ProcessRecord app = mLruProcesses.get(i);
16445                    try {
16446                        if (app.thread != null) {
16447                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
16448                                    + app.processName + " new config " + mConfiguration);
16449                            app.thread.scheduleConfigurationChanged(configCopy);
16450                        }
16451                    } catch (Exception e) {
16452                    }
16453                }
16454                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
16455                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16456                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
16457                        | Intent.FLAG_RECEIVER_FOREGROUND);
16458                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
16459                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
16460                        Process.SYSTEM_UID, UserHandle.USER_ALL);
16461                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
16462                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
16463                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16464                    broadcastIntentLocked(null, null, intent,
16465                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16466                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16467                }
16468            }
16469        }
16470
16471        boolean kept = true;
16472        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
16473        // mainStack is null during startup.
16474        if (mainStack != null) {
16475            if (changes != 0 && starting == null) {
16476                // If the configuration changed, and the caller is not already
16477                // in the process of starting an activity, then find the top
16478                // activity to check if its configuration needs to change.
16479                starting = mainStack.topRunningActivityLocked(null);
16480            }
16481
16482            if (starting != null) {
16483                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
16484                // And we need to make sure at this point that all other activities
16485                // are made visible with the correct configuration.
16486                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
16487            }
16488        }
16489
16490        if (values != null && mWindowManager != null) {
16491            mWindowManager.setNewConfiguration(mConfiguration);
16492        }
16493
16494        return kept;
16495    }
16496
16497    /**
16498     * Decide based on the configuration whether we should shouw the ANR,
16499     * crash, etc dialogs.  The idea is that if there is no affordnace to
16500     * press the on-screen buttons, we shouldn't show the dialog.
16501     *
16502     * A thought: SystemUI might also want to get told about this, the Power
16503     * dialog / global actions also might want different behaviors.
16504     */
16505    private static final boolean shouldShowDialogs(Configuration config) {
16506        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
16507                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
16508    }
16509
16510    /**
16511     * Save the locale.  You must be inside a synchronized (this) block.
16512     */
16513    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
16514        if(isDiff) {
16515            SystemProperties.set("user.language", l.getLanguage());
16516            SystemProperties.set("user.region", l.getCountry());
16517        }
16518
16519        if(isPersist) {
16520            SystemProperties.set("persist.sys.language", l.getLanguage());
16521            SystemProperties.set("persist.sys.country", l.getCountry());
16522            SystemProperties.set("persist.sys.localevar", l.getVariant());
16523
16524            mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG, l));
16525        }
16526    }
16527
16528    @Override
16529    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
16530        synchronized (this) {
16531            ActivityRecord srec = ActivityRecord.forToken(token);
16532            if (srec.task != null && srec.task.stack != null) {
16533                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
16534            }
16535        }
16536        return false;
16537    }
16538
16539    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
16540            Intent resultData) {
16541
16542        synchronized (this) {
16543            final ActivityStack stack = ActivityRecord.getStackLocked(token);
16544            if (stack != null) {
16545                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
16546            }
16547            return false;
16548        }
16549    }
16550
16551    public int getLaunchedFromUid(IBinder activityToken) {
16552        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16553        if (srec == null) {
16554            return -1;
16555        }
16556        return srec.launchedFromUid;
16557    }
16558
16559    public String getLaunchedFromPackage(IBinder activityToken) {
16560        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16561        if (srec == null) {
16562            return null;
16563        }
16564        return srec.launchedFromPackage;
16565    }
16566
16567    // =========================================================
16568    // LIFETIME MANAGEMENT
16569    // =========================================================
16570
16571    // Returns which broadcast queue the app is the current [or imminent] receiver
16572    // on, or 'null' if the app is not an active broadcast recipient.
16573    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
16574        BroadcastRecord r = app.curReceiver;
16575        if (r != null) {
16576            return r.queue;
16577        }
16578
16579        // It's not the current receiver, but it might be starting up to become one
16580        synchronized (this) {
16581            for (BroadcastQueue queue : mBroadcastQueues) {
16582                r = queue.mPendingBroadcast;
16583                if (r != null && r.curApp == app) {
16584                    // found it; report which queue it's in
16585                    return queue;
16586                }
16587            }
16588        }
16589
16590        return null;
16591    }
16592
16593    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
16594            boolean doingAll, long now) {
16595        if (mAdjSeq == app.adjSeq) {
16596            // This adjustment has already been computed.
16597            return app.curRawAdj;
16598        }
16599
16600        if (app.thread == null) {
16601            app.adjSeq = mAdjSeq;
16602            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16603            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16604            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
16605        }
16606
16607        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
16608        app.adjSource = null;
16609        app.adjTarget = null;
16610        app.empty = false;
16611        app.cached = false;
16612
16613        final int activitiesSize = app.activities.size();
16614
16615        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16616            // The max adjustment doesn't allow this app to be anything
16617            // below foreground, so it is not worth doing work for it.
16618            app.adjType = "fixed";
16619            app.adjSeq = mAdjSeq;
16620            app.curRawAdj = app.maxAdj;
16621            app.foregroundActivities = false;
16622            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
16623            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
16624            // System processes can do UI, and when they do we want to have
16625            // them trim their memory after the user leaves the UI.  To
16626            // facilitate this, here we need to determine whether or not it
16627            // is currently showing UI.
16628            app.systemNoUi = true;
16629            if (app == TOP_APP) {
16630                app.systemNoUi = false;
16631            } else if (activitiesSize > 0) {
16632                for (int j = 0; j < activitiesSize; j++) {
16633                    final ActivityRecord r = app.activities.get(j);
16634                    if (r.visible) {
16635                        app.systemNoUi = false;
16636                    }
16637                }
16638            }
16639            if (!app.systemNoUi) {
16640                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
16641            }
16642            return (app.curAdj=app.maxAdj);
16643        }
16644
16645        app.systemNoUi = false;
16646
16647        // Determine the importance of the process, starting with most
16648        // important to least, and assign an appropriate OOM adjustment.
16649        int adj;
16650        int schedGroup;
16651        int procState;
16652        boolean foregroundActivities = false;
16653        BroadcastQueue queue;
16654        if (app == TOP_APP) {
16655            // The last app on the list is the foreground app.
16656            adj = ProcessList.FOREGROUND_APP_ADJ;
16657            schedGroup = Process.THREAD_GROUP_DEFAULT;
16658            app.adjType = "top-activity";
16659            foregroundActivities = true;
16660            procState = ActivityManager.PROCESS_STATE_TOP;
16661        } else if (app.instrumentationClass != null) {
16662            // Don't want to kill running instrumentation.
16663            adj = ProcessList.FOREGROUND_APP_ADJ;
16664            schedGroup = Process.THREAD_GROUP_DEFAULT;
16665            app.adjType = "instrumentation";
16666            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16667        } else if ((queue = isReceivingBroadcast(app)) != null) {
16668            // An app that is currently receiving a broadcast also
16669            // counts as being in the foreground for OOM killer purposes.
16670            // It's placed in a sched group based on the nature of the
16671            // broadcast as reflected by which queue it's active in.
16672            adj = ProcessList.FOREGROUND_APP_ADJ;
16673            schedGroup = (queue == mFgBroadcastQueue)
16674                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16675            app.adjType = "broadcast";
16676            procState = ActivityManager.PROCESS_STATE_RECEIVER;
16677        } else if (app.executingServices.size() > 0) {
16678            // An app that is currently executing a service callback also
16679            // counts as being in the foreground.
16680            adj = ProcessList.FOREGROUND_APP_ADJ;
16681            schedGroup = app.execServicesFg ?
16682                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16683            app.adjType = "exec-service";
16684            procState = ActivityManager.PROCESS_STATE_SERVICE;
16685            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
16686        } else {
16687            // As far as we know the process is empty.  We may change our mind later.
16688            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16689            // At this point we don't actually know the adjustment.  Use the cached adj
16690            // value that the caller wants us to.
16691            adj = cachedAdj;
16692            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16693            app.cached = true;
16694            app.empty = true;
16695            app.adjType = "cch-empty";
16696        }
16697
16698        // Examine all activities if not already foreground.
16699        if (!foregroundActivities && activitiesSize > 0) {
16700            for (int j = 0; j < activitiesSize; j++) {
16701                final ActivityRecord r = app.activities.get(j);
16702                if (r.app != app) {
16703                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
16704                            + app + "?!?");
16705                    continue;
16706                }
16707                if (r.visible) {
16708                    // App has a visible activity; only upgrade adjustment.
16709                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
16710                        adj = ProcessList.VISIBLE_APP_ADJ;
16711                        app.adjType = "visible";
16712                    }
16713                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16714                        procState = ActivityManager.PROCESS_STATE_TOP;
16715                    }
16716                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16717                    app.cached = false;
16718                    app.empty = false;
16719                    foregroundActivities = true;
16720                    break;
16721                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
16722                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16723                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16724                        app.adjType = "pausing";
16725                    }
16726                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16727                        procState = ActivityManager.PROCESS_STATE_TOP;
16728                    }
16729                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16730                    app.cached = false;
16731                    app.empty = false;
16732                    foregroundActivities = true;
16733                } else if (r.state == ActivityState.STOPPING) {
16734                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16735                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16736                        app.adjType = "stopping";
16737                    }
16738                    // For the process state, we will at this point consider the
16739                    // process to be cached.  It will be cached either as an activity
16740                    // or empty depending on whether the activity is finishing.  We do
16741                    // this so that we can treat the process as cached for purposes of
16742                    // memory trimming (determing current memory level, trim command to
16743                    // send to process) since there can be an arbitrary number of stopping
16744                    // processes and they should soon all go into the cached state.
16745                    if (!r.finishing) {
16746                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
16747                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
16748                        }
16749                    }
16750                    app.cached = false;
16751                    app.empty = false;
16752                    foregroundActivities = true;
16753                } else {
16754                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16755                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
16756                        app.adjType = "cch-act";
16757                    }
16758                }
16759            }
16760        }
16761
16762        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16763            if (app.foregroundServices) {
16764                // The user is aware of this app, so make it visible.
16765                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16766                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16767                app.cached = false;
16768                app.adjType = "fg-service";
16769                schedGroup = Process.THREAD_GROUP_DEFAULT;
16770            } else if (app.forcingToForeground != null) {
16771                // The user is aware of this app, so make it visible.
16772                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16773                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16774                app.cached = false;
16775                app.adjType = "force-fg";
16776                app.adjSource = app.forcingToForeground;
16777                schedGroup = Process.THREAD_GROUP_DEFAULT;
16778            }
16779        }
16780
16781        if (app == mHeavyWeightProcess) {
16782            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
16783                // We don't want to kill the current heavy-weight process.
16784                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
16785                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16786                app.cached = false;
16787                app.adjType = "heavy";
16788            }
16789            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16790                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
16791            }
16792        }
16793
16794        if (app == mHomeProcess) {
16795            if (adj > ProcessList.HOME_APP_ADJ) {
16796                // This process is hosting what we currently consider to be the
16797                // home app, so we don't want to let it go into the background.
16798                adj = ProcessList.HOME_APP_ADJ;
16799                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16800                app.cached = false;
16801                app.adjType = "home";
16802            }
16803            if (procState > ActivityManager.PROCESS_STATE_HOME) {
16804                procState = ActivityManager.PROCESS_STATE_HOME;
16805            }
16806        }
16807
16808        if (app == mPreviousProcess && app.activities.size() > 0) {
16809            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
16810                // This was the previous process that showed UI to the user.
16811                // We want to try to keep it around more aggressively, to give
16812                // a good experience around switching between two apps.
16813                adj = ProcessList.PREVIOUS_APP_ADJ;
16814                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16815                app.cached = false;
16816                app.adjType = "previous";
16817            }
16818            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
16819                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
16820            }
16821        }
16822
16823        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
16824                + " reason=" + app.adjType);
16825
16826        // By default, we use the computed adjustment.  It may be changed if
16827        // there are applications dependent on our services or providers, but
16828        // this gives us a baseline and makes sure we don't get into an
16829        // infinite recursion.
16830        app.adjSeq = mAdjSeq;
16831        app.curRawAdj = adj;
16832        app.hasStartedServices = false;
16833
16834        if (mBackupTarget != null && app == mBackupTarget.app) {
16835            // If possible we want to avoid killing apps while they're being backed up
16836            if (adj > ProcessList.BACKUP_APP_ADJ) {
16837                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
16838                adj = ProcessList.BACKUP_APP_ADJ;
16839                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
16840                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
16841                }
16842                app.adjType = "backup";
16843                app.cached = false;
16844            }
16845            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
16846                procState = ActivityManager.PROCESS_STATE_BACKUP;
16847            }
16848        }
16849
16850        boolean mayBeTop = false;
16851
16852        for (int is = app.services.size()-1;
16853                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16854                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16855                        || procState > ActivityManager.PROCESS_STATE_TOP);
16856                is--) {
16857            ServiceRecord s = app.services.valueAt(is);
16858            if (s.startRequested) {
16859                app.hasStartedServices = true;
16860                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
16861                    procState = ActivityManager.PROCESS_STATE_SERVICE;
16862                }
16863                if (app.hasShownUi && app != mHomeProcess) {
16864                    // If this process has shown some UI, let it immediately
16865                    // go to the LRU list because it may be pretty heavy with
16866                    // UI stuff.  We'll tag it with a label just to help
16867                    // debug and understand what is going on.
16868                    if (adj > ProcessList.SERVICE_ADJ) {
16869                        app.adjType = "cch-started-ui-services";
16870                    }
16871                } else {
16872                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
16873                        // This service has seen some activity within
16874                        // recent memory, so we will keep its process ahead
16875                        // of the background processes.
16876                        if (adj > ProcessList.SERVICE_ADJ) {
16877                            adj = ProcessList.SERVICE_ADJ;
16878                            app.adjType = "started-services";
16879                            app.cached = false;
16880                        }
16881                    }
16882                    // If we have let the service slide into the background
16883                    // state, still have some text describing what it is doing
16884                    // even though the service no longer has an impact.
16885                    if (adj > ProcessList.SERVICE_ADJ) {
16886                        app.adjType = "cch-started-services";
16887                    }
16888                }
16889            }
16890            for (int conni = s.connections.size()-1;
16891                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16892                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16893                            || procState > ActivityManager.PROCESS_STATE_TOP);
16894                    conni--) {
16895                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
16896                for (int i = 0;
16897                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
16898                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16899                                || procState > ActivityManager.PROCESS_STATE_TOP);
16900                        i++) {
16901                    // XXX should compute this based on the max of
16902                    // all connected clients.
16903                    ConnectionRecord cr = clist.get(i);
16904                    if (cr.binding.client == app) {
16905                        // Binding to ourself is not interesting.
16906                        continue;
16907                    }
16908                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
16909                        ProcessRecord client = cr.binding.client;
16910                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
16911                                TOP_APP, doingAll, now);
16912                        int clientProcState = client.curProcState;
16913                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16914                            // If the other app is cached for any reason, for purposes here
16915                            // we are going to consider it empty.  The specific cached state
16916                            // doesn't propagate except under certain conditions.
16917                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16918                        }
16919                        String adjType = null;
16920                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
16921                            // Not doing bind OOM management, so treat
16922                            // this guy more like a started service.
16923                            if (app.hasShownUi && app != mHomeProcess) {
16924                                // If this process has shown some UI, let it immediately
16925                                // go to the LRU list because it may be pretty heavy with
16926                                // UI stuff.  We'll tag it with a label just to help
16927                                // debug and understand what is going on.
16928                                if (adj > clientAdj) {
16929                                    adjType = "cch-bound-ui-services";
16930                                }
16931                                app.cached = false;
16932                                clientAdj = adj;
16933                                clientProcState = procState;
16934                            } else {
16935                                if (now >= (s.lastActivity
16936                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
16937                                    // This service has not seen activity within
16938                                    // recent memory, so allow it to drop to the
16939                                    // LRU list if there is no other reason to keep
16940                                    // it around.  We'll also tag it with a label just
16941                                    // to help debug and undertand what is going on.
16942                                    if (adj > clientAdj) {
16943                                        adjType = "cch-bound-services";
16944                                    }
16945                                    clientAdj = adj;
16946                                }
16947                            }
16948                        }
16949                        if (adj > clientAdj) {
16950                            // If this process has recently shown UI, and
16951                            // the process that is binding to it is less
16952                            // important than being visible, then we don't
16953                            // care about the binding as much as we care
16954                            // about letting this process get into the LRU
16955                            // list to be killed and restarted if needed for
16956                            // memory.
16957                            if (app.hasShownUi && app != mHomeProcess
16958                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16959                                adjType = "cch-bound-ui-services";
16960                            } else {
16961                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
16962                                        |Context.BIND_IMPORTANT)) != 0) {
16963                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
16964                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
16965                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
16966                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
16967                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16968                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16969                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
16970                                    adj = clientAdj;
16971                                } else {
16972                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
16973                                        adj = ProcessList.VISIBLE_APP_ADJ;
16974                                    }
16975                                }
16976                                if (!client.cached) {
16977                                    app.cached = false;
16978                                }
16979                                adjType = "service";
16980                            }
16981                        }
16982                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
16983                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
16984                                schedGroup = Process.THREAD_GROUP_DEFAULT;
16985                            }
16986                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
16987                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
16988                                    // Special handling of clients who are in the top state.
16989                                    // We *may* want to consider this process to be in the
16990                                    // top state as well, but only if there is not another
16991                                    // reason for it to be running.  Being on the top is a
16992                                    // special state, meaning you are specifically running
16993                                    // for the current top app.  If the process is already
16994                                    // running in the background for some other reason, it
16995                                    // is more important to continue considering it to be
16996                                    // in the background state.
16997                                    mayBeTop = true;
16998                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16999                                } else {
17000                                    // Special handling for above-top states (persistent
17001                                    // processes).  These should not bring the current process
17002                                    // into the top state, since they are not on top.  Instead
17003                                    // give them the best state after that.
17004                                    clientProcState =
17005                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17006                                }
17007                            }
17008                        } else {
17009                            if (clientProcState <
17010                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
17011                                clientProcState =
17012                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
17013                            }
17014                        }
17015                        if (procState > clientProcState) {
17016                            procState = clientProcState;
17017                        }
17018                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17019                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
17020                            app.pendingUiClean = true;
17021                        }
17022                        if (adjType != null) {
17023                            app.adjType = adjType;
17024                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17025                                    .REASON_SERVICE_IN_USE;
17026                            app.adjSource = cr.binding.client;
17027                            app.adjSourceProcState = clientProcState;
17028                            app.adjTarget = s.name;
17029                        }
17030                    }
17031                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
17032                        app.treatLikeActivity = true;
17033                    }
17034                    final ActivityRecord a = cr.activity;
17035                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
17036                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
17037                                (a.visible || a.state == ActivityState.RESUMED
17038                                 || a.state == ActivityState.PAUSING)) {
17039                            adj = ProcessList.FOREGROUND_APP_ADJ;
17040                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
17041                                schedGroup = Process.THREAD_GROUP_DEFAULT;
17042                            }
17043                            app.cached = false;
17044                            app.adjType = "service";
17045                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17046                                    .REASON_SERVICE_IN_USE;
17047                            app.adjSource = a;
17048                            app.adjSourceProcState = procState;
17049                            app.adjTarget = s.name;
17050                        }
17051                    }
17052                }
17053            }
17054        }
17055
17056        for (int provi = app.pubProviders.size()-1;
17057                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17058                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17059                        || procState > ActivityManager.PROCESS_STATE_TOP);
17060                provi--) {
17061            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
17062            for (int i = cpr.connections.size()-1;
17063                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17064                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17065                            || procState > ActivityManager.PROCESS_STATE_TOP);
17066                    i--) {
17067                ContentProviderConnection conn = cpr.connections.get(i);
17068                ProcessRecord client = conn.client;
17069                if (client == app) {
17070                    // Being our own client is not interesting.
17071                    continue;
17072                }
17073                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
17074                int clientProcState = client.curProcState;
17075                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
17076                    // If the other app is cached for any reason, for purposes here
17077                    // we are going to consider it empty.
17078                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17079                }
17080                if (adj > clientAdj) {
17081                    if (app.hasShownUi && app != mHomeProcess
17082                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17083                        app.adjType = "cch-ui-provider";
17084                    } else {
17085                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
17086                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
17087                        app.adjType = "provider";
17088                    }
17089                    app.cached &= client.cached;
17090                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17091                            .REASON_PROVIDER_IN_USE;
17092                    app.adjSource = client;
17093                    app.adjSourceProcState = clientProcState;
17094                    app.adjTarget = cpr.name;
17095                }
17096                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
17097                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
17098                        // Special handling of clients who are in the top state.
17099                        // We *may* want to consider this process to be in the
17100                        // top state as well, but only if there is not another
17101                        // reason for it to be running.  Being on the top is a
17102                        // special state, meaning you are specifically running
17103                        // for the current top app.  If the process is already
17104                        // running in the background for some other reason, it
17105                        // is more important to continue considering it to be
17106                        // in the background state.
17107                        mayBeTop = true;
17108                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17109                    } else {
17110                        // Special handling for above-top states (persistent
17111                        // processes).  These should not bring the current process
17112                        // into the top state, since they are not on top.  Instead
17113                        // give them the best state after that.
17114                        clientProcState =
17115                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17116                    }
17117                }
17118                if (procState > clientProcState) {
17119                    procState = clientProcState;
17120                }
17121                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
17122                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17123                }
17124            }
17125            // If the provider has external (non-framework) process
17126            // dependencies, ensure that its adjustment is at least
17127            // FOREGROUND_APP_ADJ.
17128            if (cpr.hasExternalProcessHandles()) {
17129                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
17130                    adj = ProcessList.FOREGROUND_APP_ADJ;
17131                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17132                    app.cached = false;
17133                    app.adjType = "provider";
17134                    app.adjTarget = cpr.name;
17135                }
17136                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
17137                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17138                }
17139            }
17140        }
17141
17142        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
17143            // A client of one of our services or providers is in the top state.  We
17144            // *may* want to be in the top state, but not if we are already running in
17145            // the background for some other reason.  For the decision here, we are going
17146            // to pick out a few specific states that we want to remain in when a client
17147            // is top (states that tend to be longer-term) and otherwise allow it to go
17148            // to the top state.
17149            switch (procState) {
17150                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
17151                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
17152                case ActivityManager.PROCESS_STATE_SERVICE:
17153                    // These all are longer-term states, so pull them up to the top
17154                    // of the background states, but not all the way to the top state.
17155                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17156                    break;
17157                default:
17158                    // Otherwise, top is a better choice, so take it.
17159                    procState = ActivityManager.PROCESS_STATE_TOP;
17160                    break;
17161            }
17162        }
17163
17164        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
17165            if (app.hasClientActivities) {
17166                // This is a cached process, but with client activities.  Mark it so.
17167                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
17168                app.adjType = "cch-client-act";
17169            } else if (app.treatLikeActivity) {
17170                // This is a cached process, but somebody wants us to treat it like it has
17171                // an activity, okay!
17172                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
17173                app.adjType = "cch-as-act";
17174            }
17175        }
17176
17177        if (adj == ProcessList.SERVICE_ADJ) {
17178            if (doingAll) {
17179                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
17180                mNewNumServiceProcs++;
17181                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
17182                if (!app.serviceb) {
17183                    // This service isn't far enough down on the LRU list to
17184                    // normally be a B service, but if we are low on RAM and it
17185                    // is large we want to force it down since we would prefer to
17186                    // keep launcher over it.
17187                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
17188                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
17189                        app.serviceHighRam = true;
17190                        app.serviceb = true;
17191                        //Slog.i(TAG, "ADJ " + app + " high ram!");
17192                    } else {
17193                        mNewNumAServiceProcs++;
17194                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
17195                    }
17196                } else {
17197                    app.serviceHighRam = false;
17198                }
17199            }
17200            if (app.serviceb) {
17201                adj = ProcessList.SERVICE_B_ADJ;
17202            }
17203        }
17204
17205        app.curRawAdj = adj;
17206
17207        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
17208        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
17209        if (adj > app.maxAdj) {
17210            adj = app.maxAdj;
17211            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
17212                schedGroup = Process.THREAD_GROUP_DEFAULT;
17213            }
17214        }
17215
17216        // Do final modification to adj.  Everything we do between here and applying
17217        // the final setAdj must be done in this function, because we will also use
17218        // it when computing the final cached adj later.  Note that we don't need to
17219        // worry about this for max adj above, since max adj will always be used to
17220        // keep it out of the cached vaues.
17221        app.curAdj = app.modifyRawOomAdj(adj);
17222        app.curSchedGroup = schedGroup;
17223        app.curProcState = procState;
17224        app.foregroundActivities = foregroundActivities;
17225
17226        return app.curRawAdj;
17227    }
17228
17229    /**
17230     * Schedule PSS collection of a process.
17231     */
17232    void requestPssLocked(ProcessRecord proc, int procState) {
17233        if (mPendingPssProcesses.contains(proc)) {
17234            return;
17235        }
17236        if (mPendingPssProcesses.size() == 0) {
17237            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
17238        }
17239        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
17240        proc.pssProcState = procState;
17241        mPendingPssProcesses.add(proc);
17242    }
17243
17244    /**
17245     * Schedule PSS collection of all processes.
17246     */
17247    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
17248        if (!always) {
17249            if (now < (mLastFullPssTime +
17250                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
17251                return;
17252            }
17253        }
17254        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
17255        mLastFullPssTime = now;
17256        mFullPssPending = true;
17257        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
17258        mPendingPssProcesses.clear();
17259        for (int i=mLruProcesses.size()-1; i>=0; i--) {
17260            ProcessRecord app = mLruProcesses.get(i);
17261            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
17262                app.pssProcState = app.setProcState;
17263                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17264                        isSleeping(), now);
17265                mPendingPssProcesses.add(app);
17266            }
17267        }
17268        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
17269    }
17270
17271    /**
17272     * Ask a given process to GC right now.
17273     */
17274    final void performAppGcLocked(ProcessRecord app) {
17275        try {
17276            app.lastRequestedGc = SystemClock.uptimeMillis();
17277            if (app.thread != null) {
17278                if (app.reportLowMemory) {
17279                    app.reportLowMemory = false;
17280                    app.thread.scheduleLowMemory();
17281                } else {
17282                    app.thread.processInBackground();
17283                }
17284            }
17285        } catch (Exception e) {
17286            // whatever.
17287        }
17288    }
17289
17290    /**
17291     * Returns true if things are idle enough to perform GCs.
17292     */
17293    private final boolean canGcNowLocked() {
17294        boolean processingBroadcasts = false;
17295        for (BroadcastQueue q : mBroadcastQueues) {
17296            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
17297                processingBroadcasts = true;
17298            }
17299        }
17300        return !processingBroadcasts
17301                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
17302    }
17303
17304    /**
17305     * Perform GCs on all processes that are waiting for it, but only
17306     * if things are idle.
17307     */
17308    final void performAppGcsLocked() {
17309        final int N = mProcessesToGc.size();
17310        if (N <= 0) {
17311            return;
17312        }
17313        if (canGcNowLocked()) {
17314            while (mProcessesToGc.size() > 0) {
17315                ProcessRecord proc = mProcessesToGc.remove(0);
17316                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
17317                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
17318                            <= SystemClock.uptimeMillis()) {
17319                        // To avoid spamming the system, we will GC processes one
17320                        // at a time, waiting a few seconds between each.
17321                        performAppGcLocked(proc);
17322                        scheduleAppGcsLocked();
17323                        return;
17324                    } else {
17325                        // It hasn't been long enough since we last GCed this
17326                        // process...  put it in the list to wait for its time.
17327                        addProcessToGcListLocked(proc);
17328                        break;
17329                    }
17330                }
17331            }
17332
17333            scheduleAppGcsLocked();
17334        }
17335    }
17336
17337    /**
17338     * If all looks good, perform GCs on all processes waiting for them.
17339     */
17340    final void performAppGcsIfAppropriateLocked() {
17341        if (canGcNowLocked()) {
17342            performAppGcsLocked();
17343            return;
17344        }
17345        // Still not idle, wait some more.
17346        scheduleAppGcsLocked();
17347    }
17348
17349    /**
17350     * Schedule the execution of all pending app GCs.
17351     */
17352    final void scheduleAppGcsLocked() {
17353        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
17354
17355        if (mProcessesToGc.size() > 0) {
17356            // Schedule a GC for the time to the next process.
17357            ProcessRecord proc = mProcessesToGc.get(0);
17358            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
17359
17360            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
17361            long now = SystemClock.uptimeMillis();
17362            if (when < (now+GC_TIMEOUT)) {
17363                when = now + GC_TIMEOUT;
17364            }
17365            mHandler.sendMessageAtTime(msg, when);
17366        }
17367    }
17368
17369    /**
17370     * Add a process to the array of processes waiting to be GCed.  Keeps the
17371     * list in sorted order by the last GC time.  The process can't already be
17372     * on the list.
17373     */
17374    final void addProcessToGcListLocked(ProcessRecord proc) {
17375        boolean added = false;
17376        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
17377            if (mProcessesToGc.get(i).lastRequestedGc <
17378                    proc.lastRequestedGc) {
17379                added = true;
17380                mProcessesToGc.add(i+1, proc);
17381                break;
17382            }
17383        }
17384        if (!added) {
17385            mProcessesToGc.add(0, proc);
17386        }
17387    }
17388
17389    /**
17390     * Set up to ask a process to GC itself.  This will either do it
17391     * immediately, or put it on the list of processes to gc the next
17392     * time things are idle.
17393     */
17394    final void scheduleAppGcLocked(ProcessRecord app) {
17395        long now = SystemClock.uptimeMillis();
17396        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
17397            return;
17398        }
17399        if (!mProcessesToGc.contains(app)) {
17400            addProcessToGcListLocked(app);
17401            scheduleAppGcsLocked();
17402        }
17403    }
17404
17405    final void checkExcessivePowerUsageLocked(boolean doKills) {
17406        updateCpuStatsNow();
17407
17408        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17409        boolean doWakeKills = doKills;
17410        boolean doCpuKills = doKills;
17411        if (mLastPowerCheckRealtime == 0) {
17412            doWakeKills = false;
17413        }
17414        if (mLastPowerCheckUptime == 0) {
17415            doCpuKills = false;
17416        }
17417        if (stats.isScreenOn()) {
17418            doWakeKills = false;
17419        }
17420        final long curRealtime = SystemClock.elapsedRealtime();
17421        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
17422        final long curUptime = SystemClock.uptimeMillis();
17423        final long uptimeSince = curUptime - mLastPowerCheckUptime;
17424        mLastPowerCheckRealtime = curRealtime;
17425        mLastPowerCheckUptime = curUptime;
17426        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
17427            doWakeKills = false;
17428        }
17429        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
17430            doCpuKills = false;
17431        }
17432        int i = mLruProcesses.size();
17433        while (i > 0) {
17434            i--;
17435            ProcessRecord app = mLruProcesses.get(i);
17436            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17437                long wtime;
17438                synchronized (stats) {
17439                    wtime = stats.getProcessWakeTime(app.info.uid,
17440                            app.pid, curRealtime);
17441                }
17442                long wtimeUsed = wtime - app.lastWakeTime;
17443                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
17444                if (DEBUG_POWER) {
17445                    StringBuilder sb = new StringBuilder(128);
17446                    sb.append("Wake for ");
17447                    app.toShortString(sb);
17448                    sb.append(": over ");
17449                    TimeUtils.formatDuration(realtimeSince, sb);
17450                    sb.append(" used ");
17451                    TimeUtils.formatDuration(wtimeUsed, sb);
17452                    sb.append(" (");
17453                    sb.append((wtimeUsed*100)/realtimeSince);
17454                    sb.append("%)");
17455                    Slog.i(TAG, sb.toString());
17456                    sb.setLength(0);
17457                    sb.append("CPU for ");
17458                    app.toShortString(sb);
17459                    sb.append(": over ");
17460                    TimeUtils.formatDuration(uptimeSince, sb);
17461                    sb.append(" used ");
17462                    TimeUtils.formatDuration(cputimeUsed, sb);
17463                    sb.append(" (");
17464                    sb.append((cputimeUsed*100)/uptimeSince);
17465                    sb.append("%)");
17466                    Slog.i(TAG, sb.toString());
17467                }
17468                // If a process has held a wake lock for more
17469                // than 50% of the time during this period,
17470                // that sounds bad.  Kill!
17471                if (doWakeKills && realtimeSince > 0
17472                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
17473                    synchronized (stats) {
17474                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
17475                                realtimeSince, wtimeUsed);
17476                    }
17477                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
17478                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
17479                } else if (doCpuKills && uptimeSince > 0
17480                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
17481                    synchronized (stats) {
17482                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
17483                                uptimeSince, cputimeUsed);
17484                    }
17485                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
17486                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
17487                } else {
17488                    app.lastWakeTime = wtime;
17489                    app.lastCpuTime = app.curCpuTime;
17490                }
17491            }
17492        }
17493    }
17494
17495    private final boolean applyOomAdjLocked(ProcessRecord app,
17496            ProcessRecord TOP_APP, boolean doingAll, long now) {
17497        boolean success = true;
17498
17499        if (app.curRawAdj != app.setRawAdj) {
17500            app.setRawAdj = app.curRawAdj;
17501        }
17502
17503        int changes = 0;
17504
17505        if (app.curAdj != app.setAdj) {
17506            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
17507            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
17508                TAG, "Set " + app.pid + " " + app.processName +
17509                " adj " + app.curAdj + ": " + app.adjType);
17510            app.setAdj = app.curAdj;
17511        }
17512
17513        if (app.setSchedGroup != app.curSchedGroup) {
17514            app.setSchedGroup = app.curSchedGroup;
17515            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17516                    "Setting process group of " + app.processName
17517                    + " to " + app.curSchedGroup);
17518            if (app.waitingToKill != null &&
17519                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
17520                app.kill(app.waitingToKill, true);
17521                success = false;
17522            } else {
17523                if (true) {
17524                    long oldId = Binder.clearCallingIdentity();
17525                    try {
17526                        Process.setProcessGroup(app.pid, app.curSchedGroup);
17527                    } catch (Exception e) {
17528                        Slog.w(TAG, "Failed setting process group of " + app.pid
17529                                + " to " + app.curSchedGroup);
17530                        e.printStackTrace();
17531                    } finally {
17532                        Binder.restoreCallingIdentity(oldId);
17533                    }
17534                } else {
17535                    if (app.thread != null) {
17536                        try {
17537                            app.thread.setSchedulingGroup(app.curSchedGroup);
17538                        } catch (RemoteException e) {
17539                        }
17540                    }
17541                }
17542                Process.setSwappiness(app.pid,
17543                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
17544            }
17545        }
17546        if (app.repForegroundActivities != app.foregroundActivities) {
17547            app.repForegroundActivities = app.foregroundActivities;
17548            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
17549        }
17550        if (app.repProcState != app.curProcState) {
17551            app.repProcState = app.curProcState;
17552            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
17553            if (app.thread != null) {
17554                try {
17555                    if (false) {
17556                        //RuntimeException h = new RuntimeException("here");
17557                        Slog.i(TAG, "Sending new process state " + app.repProcState
17558                                + " to " + app /*, h*/);
17559                    }
17560                    app.thread.setProcessState(app.repProcState);
17561                } catch (RemoteException e) {
17562                }
17563            }
17564        }
17565        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
17566                app.setProcState)) {
17567            app.lastStateTime = now;
17568            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17569                    isSleeping(), now);
17570            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
17571                    + ProcessList.makeProcStateString(app.setProcState) + " to "
17572                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
17573                    + (app.nextPssTime-now) + ": " + app);
17574        } else {
17575            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
17576                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
17577                requestPssLocked(app, app.setProcState);
17578                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
17579                        isSleeping(), now);
17580            } else if (false && DEBUG_PSS) {
17581                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
17582            }
17583        }
17584        if (app.setProcState != app.curProcState) {
17585            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17586                    "Proc state change of " + app.processName
17587                    + " to " + app.curProcState);
17588            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
17589            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
17590            if (setImportant && !curImportant) {
17591                // This app is no longer something we consider important enough to allow to
17592                // use arbitrary amounts of battery power.  Note
17593                // its current wake lock time to later know to kill it if
17594                // it is not behaving well.
17595                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17596                synchronized (stats) {
17597                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
17598                            app.pid, SystemClock.elapsedRealtime());
17599                }
17600                app.lastCpuTime = app.curCpuTime;
17601
17602            }
17603            app.setProcState = app.curProcState;
17604            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17605                app.notCachedSinceIdle = false;
17606            }
17607            if (!doingAll) {
17608                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
17609            } else {
17610                app.procStateChanged = true;
17611            }
17612        }
17613
17614        if (changes != 0) {
17615            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
17616            int i = mPendingProcessChanges.size()-1;
17617            ProcessChangeItem item = null;
17618            while (i >= 0) {
17619                item = mPendingProcessChanges.get(i);
17620                if (item.pid == app.pid) {
17621                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
17622                    break;
17623                }
17624                i--;
17625            }
17626            if (i < 0) {
17627                // No existing item in pending changes; need a new one.
17628                final int NA = mAvailProcessChanges.size();
17629                if (NA > 0) {
17630                    item = mAvailProcessChanges.remove(NA-1);
17631                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
17632                } else {
17633                    item = new ProcessChangeItem();
17634                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
17635                }
17636                item.changes = 0;
17637                item.pid = app.pid;
17638                item.uid = app.info.uid;
17639                if (mPendingProcessChanges.size() == 0) {
17640                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
17641                            "*** Enqueueing dispatch processes changed!");
17642                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
17643                }
17644                mPendingProcessChanges.add(item);
17645            }
17646            item.changes |= changes;
17647            item.processState = app.repProcState;
17648            item.foregroundActivities = app.repForegroundActivities;
17649            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
17650                    + Integer.toHexString(System.identityHashCode(item))
17651                    + " " + app.toShortString() + ": changes=" + item.changes
17652                    + " procState=" + item.processState
17653                    + " foreground=" + item.foregroundActivities
17654                    + " type=" + app.adjType + " source=" + app.adjSource
17655                    + " target=" + app.adjTarget);
17656        }
17657
17658        return success;
17659    }
17660
17661    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
17662        if (proc.thread != null) {
17663            if (proc.baseProcessTracker != null) {
17664                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
17665            }
17666            if (proc.repProcState >= 0) {
17667                mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
17668                        proc.repProcState);
17669            }
17670        }
17671    }
17672
17673    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
17674            ProcessRecord TOP_APP, boolean doingAll, long now) {
17675        if (app.thread == null) {
17676            return false;
17677        }
17678
17679        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
17680
17681        return applyOomAdjLocked(app, TOP_APP, doingAll, now);
17682    }
17683
17684    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
17685            boolean oomAdj) {
17686        if (isForeground != proc.foregroundServices) {
17687            proc.foregroundServices = isForeground;
17688            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
17689                    proc.info.uid);
17690            if (isForeground) {
17691                if (curProcs == null) {
17692                    curProcs = new ArrayList<ProcessRecord>();
17693                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
17694                }
17695                if (!curProcs.contains(proc)) {
17696                    curProcs.add(proc);
17697                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
17698                            proc.info.packageName, proc.info.uid);
17699                }
17700            } else {
17701                if (curProcs != null) {
17702                    if (curProcs.remove(proc)) {
17703                        mBatteryStatsService.noteEvent(
17704                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
17705                                proc.info.packageName, proc.info.uid);
17706                        if (curProcs.size() <= 0) {
17707                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
17708                        }
17709                    }
17710                }
17711            }
17712            if (oomAdj) {
17713                updateOomAdjLocked();
17714            }
17715        }
17716    }
17717
17718    private final ActivityRecord resumedAppLocked() {
17719        ActivityRecord act = mStackSupervisor.resumedAppLocked();
17720        String pkg;
17721        int uid;
17722        if (act != null) {
17723            pkg = act.packageName;
17724            uid = act.info.applicationInfo.uid;
17725        } else {
17726            pkg = null;
17727            uid = -1;
17728        }
17729        // Has the UID or resumed package name changed?
17730        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
17731                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
17732            if (mCurResumedPackage != null) {
17733                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
17734                        mCurResumedPackage, mCurResumedUid);
17735            }
17736            mCurResumedPackage = pkg;
17737            mCurResumedUid = uid;
17738            if (mCurResumedPackage != null) {
17739                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
17740                        mCurResumedPackage, mCurResumedUid);
17741            }
17742        }
17743        return act;
17744    }
17745
17746    final boolean updateOomAdjLocked(ProcessRecord app) {
17747        final ActivityRecord TOP_ACT = resumedAppLocked();
17748        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17749        final boolean wasCached = app.cached;
17750
17751        mAdjSeq++;
17752
17753        // This is the desired cached adjusment we want to tell it to use.
17754        // If our app is currently cached, we know it, and that is it.  Otherwise,
17755        // we don't know it yet, and it needs to now be cached we will then
17756        // need to do a complete oom adj.
17757        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
17758                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
17759        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
17760                SystemClock.uptimeMillis());
17761        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
17762            // Changed to/from cached state, so apps after it in the LRU
17763            // list may also be changed.
17764            updateOomAdjLocked();
17765        }
17766        return success;
17767    }
17768
17769    final void updateOomAdjLocked() {
17770        final ActivityRecord TOP_ACT = resumedAppLocked();
17771        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17772        final long now = SystemClock.uptimeMillis();
17773        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
17774        final int N = mLruProcesses.size();
17775
17776        if (false) {
17777            RuntimeException e = new RuntimeException();
17778            e.fillInStackTrace();
17779            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
17780        }
17781
17782        mAdjSeq++;
17783        mNewNumServiceProcs = 0;
17784        mNewNumAServiceProcs = 0;
17785
17786        final int emptyProcessLimit;
17787        final int cachedProcessLimit;
17788        if (mProcessLimit <= 0) {
17789            emptyProcessLimit = cachedProcessLimit = 0;
17790        } else if (mProcessLimit == 1) {
17791            emptyProcessLimit = 1;
17792            cachedProcessLimit = 0;
17793        } else {
17794            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
17795            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
17796        }
17797
17798        // Let's determine how many processes we have running vs.
17799        // how many slots we have for background processes; we may want
17800        // to put multiple processes in a slot of there are enough of
17801        // them.
17802        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
17803                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
17804        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
17805        if (numEmptyProcs > cachedProcessLimit) {
17806            // If there are more empty processes than our limit on cached
17807            // processes, then use the cached process limit for the factor.
17808            // This ensures that the really old empty processes get pushed
17809            // down to the bottom, so if we are running low on memory we will
17810            // have a better chance at keeping around more cached processes
17811            // instead of a gazillion empty processes.
17812            numEmptyProcs = cachedProcessLimit;
17813        }
17814        int emptyFactor = numEmptyProcs/numSlots;
17815        if (emptyFactor < 1) emptyFactor = 1;
17816        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
17817        if (cachedFactor < 1) cachedFactor = 1;
17818        int stepCached = 0;
17819        int stepEmpty = 0;
17820        int numCached = 0;
17821        int numEmpty = 0;
17822        int numTrimming = 0;
17823
17824        mNumNonCachedProcs = 0;
17825        mNumCachedHiddenProcs = 0;
17826
17827        // First update the OOM adjustment for each of the
17828        // application processes based on their current state.
17829        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
17830        int nextCachedAdj = curCachedAdj+1;
17831        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
17832        int nextEmptyAdj = curEmptyAdj+2;
17833        for (int i=N-1; i>=0; i--) {
17834            ProcessRecord app = mLruProcesses.get(i);
17835            if (!app.killedByAm && app.thread != null) {
17836                app.procStateChanged = false;
17837                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
17838
17839                // If we haven't yet assigned the final cached adj
17840                // to the process, do that now.
17841                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
17842                    switch (app.curProcState) {
17843                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
17844                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
17845                            // This process is a cached process holding activities...
17846                            // assign it the next cached value for that type, and then
17847                            // step that cached level.
17848                            app.curRawAdj = curCachedAdj;
17849                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
17850                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
17851                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
17852                                    + ")");
17853                            if (curCachedAdj != nextCachedAdj) {
17854                                stepCached++;
17855                                if (stepCached >= cachedFactor) {
17856                                    stepCached = 0;
17857                                    curCachedAdj = nextCachedAdj;
17858                                    nextCachedAdj += 2;
17859                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
17860                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
17861                                    }
17862                                }
17863                            }
17864                            break;
17865                        default:
17866                            // For everything else, assign next empty cached process
17867                            // level and bump that up.  Note that this means that
17868                            // long-running services that have dropped down to the
17869                            // cached level will be treated as empty (since their process
17870                            // state is still as a service), which is what we want.
17871                            app.curRawAdj = curEmptyAdj;
17872                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
17873                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
17874                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
17875                                    + ")");
17876                            if (curEmptyAdj != nextEmptyAdj) {
17877                                stepEmpty++;
17878                                if (stepEmpty >= emptyFactor) {
17879                                    stepEmpty = 0;
17880                                    curEmptyAdj = nextEmptyAdj;
17881                                    nextEmptyAdj += 2;
17882                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
17883                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
17884                                    }
17885                                }
17886                            }
17887                            break;
17888                    }
17889                }
17890
17891                applyOomAdjLocked(app, TOP_APP, true, now);
17892
17893                // Count the number of process types.
17894                switch (app.curProcState) {
17895                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
17896                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
17897                        mNumCachedHiddenProcs++;
17898                        numCached++;
17899                        if (numCached > cachedProcessLimit) {
17900                            app.kill("cached #" + numCached, true);
17901                        }
17902                        break;
17903                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
17904                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
17905                                && app.lastActivityTime < oldTime) {
17906                            app.kill("empty for "
17907                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
17908                                    / 1000) + "s", true);
17909                        } else {
17910                            numEmpty++;
17911                            if (numEmpty > emptyProcessLimit) {
17912                                app.kill("empty #" + numEmpty, true);
17913                            }
17914                        }
17915                        break;
17916                    default:
17917                        mNumNonCachedProcs++;
17918                        break;
17919                }
17920
17921                if (app.isolated && app.services.size() <= 0) {
17922                    // If this is an isolated process, and there are no
17923                    // services running in it, then the process is no longer
17924                    // needed.  We agressively kill these because we can by
17925                    // definition not re-use the same process again, and it is
17926                    // good to avoid having whatever code was running in them
17927                    // left sitting around after no longer needed.
17928                    app.kill("isolated not needed", true);
17929                }
17930
17931                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
17932                        && !app.killedByAm) {
17933                    numTrimming++;
17934                }
17935            }
17936        }
17937
17938        mNumServiceProcs = mNewNumServiceProcs;
17939
17940        // Now determine the memory trimming level of background processes.
17941        // Unfortunately we need to start at the back of the list to do this
17942        // properly.  We only do this if the number of background apps we
17943        // are managing to keep around is less than half the maximum we desire;
17944        // if we are keeping a good number around, we'll let them use whatever
17945        // memory they want.
17946        final int numCachedAndEmpty = numCached + numEmpty;
17947        int memFactor;
17948        if (numCached <= ProcessList.TRIM_CACHED_APPS
17949                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
17950            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
17951                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
17952            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
17953                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
17954            } else {
17955                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
17956            }
17957        } else {
17958            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
17959        }
17960        // We always allow the memory level to go up (better).  We only allow it to go
17961        // down if we are in a state where that is allowed, *and* the total number of processes
17962        // has gone down since last time.
17963        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
17964                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
17965                + " last=" + mLastNumProcesses);
17966        if (memFactor > mLastMemoryLevel) {
17967            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
17968                memFactor = mLastMemoryLevel;
17969                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
17970            }
17971        }
17972        mLastMemoryLevel = memFactor;
17973        mLastNumProcesses = mLruProcesses.size();
17974        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
17975        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
17976        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
17977            if (mLowRamStartTime == 0) {
17978                mLowRamStartTime = now;
17979            }
17980            int step = 0;
17981            int fgTrimLevel;
17982            switch (memFactor) {
17983                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
17984                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
17985                    break;
17986                case ProcessStats.ADJ_MEM_FACTOR_LOW:
17987                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
17988                    break;
17989                default:
17990                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
17991                    break;
17992            }
17993            int factor = numTrimming/3;
17994            int minFactor = 2;
17995            if (mHomeProcess != null) minFactor++;
17996            if (mPreviousProcess != null) minFactor++;
17997            if (factor < minFactor) factor = minFactor;
17998            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
17999            for (int i=N-1; i>=0; i--) {
18000                ProcessRecord app = mLruProcesses.get(i);
18001                if (allChanged || app.procStateChanged) {
18002                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
18003                    app.procStateChanged = false;
18004                }
18005                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
18006                        && !app.killedByAm) {
18007                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
18008                        try {
18009                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18010                                    "Trimming memory of " + app.processName
18011                                    + " to " + curLevel);
18012                            app.thread.scheduleTrimMemory(curLevel);
18013                        } catch (RemoteException e) {
18014                        }
18015                        if (false) {
18016                            // For now we won't do this; our memory trimming seems
18017                            // to be good enough at this point that destroying
18018                            // activities causes more harm than good.
18019                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
18020                                    && app != mHomeProcess && app != mPreviousProcess) {
18021                                // Need to do this on its own message because the stack may not
18022                                // be in a consistent state at this point.
18023                                // For these apps we will also finish their activities
18024                                // to help them free memory.
18025                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
18026                            }
18027                        }
18028                    }
18029                    app.trimMemoryLevel = curLevel;
18030                    step++;
18031                    if (step >= factor) {
18032                        step = 0;
18033                        switch (curLevel) {
18034                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
18035                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
18036                                break;
18037                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
18038                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
18039                                break;
18040                        }
18041                    }
18042                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
18043                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
18044                            && app.thread != null) {
18045                        try {
18046                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18047                                    "Trimming memory of heavy-weight " + app.processName
18048                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
18049                            app.thread.scheduleTrimMemory(
18050                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
18051                        } catch (RemoteException e) {
18052                        }
18053                    }
18054                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
18055                } else {
18056                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
18057                            || app.systemNoUi) && app.pendingUiClean) {
18058                        // If this application is now in the background and it
18059                        // had done UI, then give it the special trim level to
18060                        // have it free UI resources.
18061                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
18062                        if (app.trimMemoryLevel < level && app.thread != null) {
18063                            try {
18064                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18065                                        "Trimming memory of bg-ui " + app.processName
18066                                        + " to " + level);
18067                                app.thread.scheduleTrimMemory(level);
18068                            } catch (RemoteException e) {
18069                            }
18070                        }
18071                        app.pendingUiClean = false;
18072                    }
18073                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
18074                        try {
18075                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18076                                    "Trimming memory of fg " + app.processName
18077                                    + " to " + fgTrimLevel);
18078                            app.thread.scheduleTrimMemory(fgTrimLevel);
18079                        } catch (RemoteException e) {
18080                        }
18081                    }
18082                    app.trimMemoryLevel = fgTrimLevel;
18083                }
18084            }
18085        } else {
18086            if (mLowRamStartTime != 0) {
18087                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
18088                mLowRamStartTime = 0;
18089            }
18090            for (int i=N-1; i>=0; i--) {
18091                ProcessRecord app = mLruProcesses.get(i);
18092                if (allChanged || app.procStateChanged) {
18093                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
18094                    app.procStateChanged = false;
18095                }
18096                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
18097                        || app.systemNoUi) && app.pendingUiClean) {
18098                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
18099                            && app.thread != null) {
18100                        try {
18101                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18102                                    "Trimming memory of ui hidden " + app.processName
18103                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
18104                            app.thread.scheduleTrimMemory(
18105                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
18106                        } catch (RemoteException e) {
18107                        }
18108                    }
18109                    app.pendingUiClean = false;
18110                }
18111                app.trimMemoryLevel = 0;
18112            }
18113        }
18114
18115        if (mAlwaysFinishActivities) {
18116            // Need to do this on its own message because the stack may not
18117            // be in a consistent state at this point.
18118            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
18119        }
18120
18121        if (allChanged) {
18122            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
18123        }
18124
18125        if (mProcessStats.shouldWriteNowLocked(now)) {
18126            mHandler.post(new Runnable() {
18127                @Override public void run() {
18128                    synchronized (ActivityManagerService.this) {
18129                        mProcessStats.writeStateAsyncLocked();
18130                    }
18131                }
18132            });
18133        }
18134
18135        if (DEBUG_OOM_ADJ) {
18136            if (false) {
18137                RuntimeException here = new RuntimeException("here");
18138                here.fillInStackTrace();
18139                Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms", here);
18140            } else {
18141                Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
18142            }
18143        }
18144    }
18145
18146    final void trimApplications() {
18147        synchronized (this) {
18148            int i;
18149
18150            // First remove any unused application processes whose package
18151            // has been removed.
18152            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
18153                final ProcessRecord app = mRemovedProcesses.get(i);
18154                if (app.activities.size() == 0
18155                        && app.curReceiver == null && app.services.size() == 0) {
18156                    Slog.i(
18157                        TAG, "Exiting empty application process "
18158                        + app.processName + " ("
18159                        + (app.thread != null ? app.thread.asBinder() : null)
18160                        + ")\n");
18161                    if (app.pid > 0 && app.pid != MY_PID) {
18162                        app.kill("empty", false);
18163                    } else {
18164                        try {
18165                            app.thread.scheduleExit();
18166                        } catch (Exception e) {
18167                            // Ignore exceptions.
18168                        }
18169                    }
18170                    cleanUpApplicationRecordLocked(app, false, true, -1);
18171                    mRemovedProcesses.remove(i);
18172
18173                    if (app.persistent) {
18174                        addAppLocked(app.info, false, null /* ABI override */);
18175                    }
18176                }
18177            }
18178
18179            // Now update the oom adj for all processes.
18180            updateOomAdjLocked();
18181        }
18182    }
18183
18184    /** This method sends the specified signal to each of the persistent apps */
18185    public void signalPersistentProcesses(int sig) throws RemoteException {
18186        if (sig != Process.SIGNAL_USR1) {
18187            throw new SecurityException("Only SIGNAL_USR1 is allowed");
18188        }
18189
18190        synchronized (this) {
18191            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
18192                    != PackageManager.PERMISSION_GRANTED) {
18193                throw new SecurityException("Requires permission "
18194                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
18195            }
18196
18197            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
18198                ProcessRecord r = mLruProcesses.get(i);
18199                if (r.thread != null && r.persistent) {
18200                    Process.sendSignal(r.pid, sig);
18201                }
18202            }
18203        }
18204    }
18205
18206    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
18207        if (proc == null || proc == mProfileProc) {
18208            proc = mProfileProc;
18209            profileType = mProfileType;
18210            clearProfilerLocked();
18211        }
18212        if (proc == null) {
18213            return;
18214        }
18215        try {
18216            proc.thread.profilerControl(false, null, profileType);
18217        } catch (RemoteException e) {
18218            throw new IllegalStateException("Process disappeared");
18219        }
18220    }
18221
18222    private void clearProfilerLocked() {
18223        if (mProfileFd != null) {
18224            try {
18225                mProfileFd.close();
18226            } catch (IOException e) {
18227            }
18228        }
18229        mProfileApp = null;
18230        mProfileProc = null;
18231        mProfileFile = null;
18232        mProfileType = 0;
18233        mAutoStopProfiler = false;
18234        mSamplingInterval = 0;
18235    }
18236
18237    public boolean profileControl(String process, int userId, boolean start,
18238            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
18239
18240        try {
18241            synchronized (this) {
18242                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
18243                // its own permission.
18244                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
18245                        != PackageManager.PERMISSION_GRANTED) {
18246                    throw new SecurityException("Requires permission "
18247                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
18248                }
18249
18250                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
18251                    throw new IllegalArgumentException("null profile info or fd");
18252                }
18253
18254                ProcessRecord proc = null;
18255                if (process != null) {
18256                    proc = findProcessLocked(process, userId, "profileControl");
18257                }
18258
18259                if (start && (proc == null || proc.thread == null)) {
18260                    throw new IllegalArgumentException("Unknown process: " + process);
18261                }
18262
18263                if (start) {
18264                    stopProfilerLocked(null, 0);
18265                    setProfileApp(proc.info, proc.processName, profilerInfo);
18266                    mProfileProc = proc;
18267                    mProfileType = profileType;
18268                    ParcelFileDescriptor fd = profilerInfo.profileFd;
18269                    try {
18270                        fd = fd.dup();
18271                    } catch (IOException e) {
18272                        fd = null;
18273                    }
18274                    profilerInfo.profileFd = fd;
18275                    proc.thread.profilerControl(start, profilerInfo, profileType);
18276                    fd = null;
18277                    mProfileFd = null;
18278                } else {
18279                    stopProfilerLocked(proc, profileType);
18280                    if (profilerInfo != null && profilerInfo.profileFd != null) {
18281                        try {
18282                            profilerInfo.profileFd.close();
18283                        } catch (IOException e) {
18284                        }
18285                    }
18286                }
18287
18288                return true;
18289            }
18290        } catch (RemoteException e) {
18291            throw new IllegalStateException("Process disappeared");
18292        } finally {
18293            if (profilerInfo != null && profilerInfo.profileFd != null) {
18294                try {
18295                    profilerInfo.profileFd.close();
18296                } catch (IOException e) {
18297                }
18298            }
18299        }
18300    }
18301
18302    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
18303        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18304                userId, true, ALLOW_FULL_ONLY, callName, null);
18305        ProcessRecord proc = null;
18306        try {
18307            int pid = Integer.parseInt(process);
18308            synchronized (mPidsSelfLocked) {
18309                proc = mPidsSelfLocked.get(pid);
18310            }
18311        } catch (NumberFormatException e) {
18312        }
18313
18314        if (proc == null) {
18315            ArrayMap<String, SparseArray<ProcessRecord>> all
18316                    = mProcessNames.getMap();
18317            SparseArray<ProcessRecord> procs = all.get(process);
18318            if (procs != null && procs.size() > 0) {
18319                proc = procs.valueAt(0);
18320                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
18321                    for (int i=1; i<procs.size(); i++) {
18322                        ProcessRecord thisProc = procs.valueAt(i);
18323                        if (thisProc.userId == userId) {
18324                            proc = thisProc;
18325                            break;
18326                        }
18327                    }
18328                }
18329            }
18330        }
18331
18332        return proc;
18333    }
18334
18335    public boolean dumpHeap(String process, int userId, boolean managed,
18336            String path, ParcelFileDescriptor fd) throws RemoteException {
18337
18338        try {
18339            synchronized (this) {
18340                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
18341                // its own permission (same as profileControl).
18342                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
18343                        != PackageManager.PERMISSION_GRANTED) {
18344                    throw new SecurityException("Requires permission "
18345                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
18346                }
18347
18348                if (fd == null) {
18349                    throw new IllegalArgumentException("null fd");
18350                }
18351
18352                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
18353                if (proc == null || proc.thread == null) {
18354                    throw new IllegalArgumentException("Unknown process: " + process);
18355                }
18356
18357                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
18358                if (!isDebuggable) {
18359                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
18360                        throw new SecurityException("Process not debuggable: " + proc);
18361                    }
18362                }
18363
18364                proc.thread.dumpHeap(managed, path, fd);
18365                fd = null;
18366                return true;
18367            }
18368        } catch (RemoteException e) {
18369            throw new IllegalStateException("Process disappeared");
18370        } finally {
18371            if (fd != null) {
18372                try {
18373                    fd.close();
18374                } catch (IOException e) {
18375                }
18376            }
18377        }
18378    }
18379
18380    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
18381    public void monitor() {
18382        synchronized (this) { }
18383    }
18384
18385    void onCoreSettingsChange(Bundle settings) {
18386        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
18387            ProcessRecord processRecord = mLruProcesses.get(i);
18388            try {
18389                if (processRecord.thread != null) {
18390                    processRecord.thread.setCoreSettings(settings);
18391                }
18392            } catch (RemoteException re) {
18393                /* ignore */
18394            }
18395        }
18396    }
18397
18398    // Multi-user methods
18399
18400    /**
18401     * Start user, if its not already running, but don't bring it to foreground.
18402     */
18403    @Override
18404    public boolean startUserInBackground(final int userId) {
18405        return startUser(userId, /* foreground */ false);
18406    }
18407
18408    /**
18409     * Start user, if its not already running, and bring it to foreground.
18410     */
18411    boolean startUserInForeground(final int userId, Dialog dlg) {
18412        boolean result = startUser(userId, /* foreground */ true);
18413        dlg.dismiss();
18414        return result;
18415    }
18416
18417    /**
18418     * Refreshes the list of users related to the current user when either a
18419     * user switch happens or when a new related user is started in the
18420     * background.
18421     */
18422    private void updateCurrentProfileIdsLocked() {
18423        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18424                mCurrentUserId, false /* enabledOnly */);
18425        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
18426        for (int i = 0; i < currentProfileIds.length; i++) {
18427            currentProfileIds[i] = profiles.get(i).id;
18428        }
18429        mCurrentProfileIds = currentProfileIds;
18430
18431        synchronized (mUserProfileGroupIdsSelfLocked) {
18432            mUserProfileGroupIdsSelfLocked.clear();
18433            final List<UserInfo> users = getUserManagerLocked().getUsers(false);
18434            for (int i = 0; i < users.size(); i++) {
18435                UserInfo user = users.get(i);
18436                if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
18437                    mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
18438                }
18439            }
18440        }
18441    }
18442
18443    private Set getProfileIdsLocked(int userId) {
18444        Set userIds = new HashSet<Integer>();
18445        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18446                userId, false /* enabledOnly */);
18447        for (UserInfo user : profiles) {
18448            userIds.add(Integer.valueOf(user.id));
18449        }
18450        return userIds;
18451    }
18452
18453    @Override
18454    public boolean switchUser(final int userId) {
18455        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
18456        String userName;
18457        synchronized (this) {
18458            UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18459            if (userInfo == null) {
18460                Slog.w(TAG, "No user info for user #" + userId);
18461                return false;
18462            }
18463            if (userInfo.isManagedProfile()) {
18464                Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18465                return false;
18466            }
18467            userName = userInfo.name;
18468            mTargetUserId = userId;
18469        }
18470        mHandler.removeMessages(START_USER_SWITCH_MSG);
18471        mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName));
18472        return true;
18473    }
18474
18475    private void showUserSwitchDialog(int userId, String userName) {
18476        // The dialog will show and then initiate the user switch by calling startUserInForeground
18477        Dialog d = new UserSwitchingDialog(this, mContext, userId, userName,
18478                true /* above system */);
18479        d.show();
18480    }
18481
18482    private boolean startUser(final int userId, final boolean foreground) {
18483        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18484                != PackageManager.PERMISSION_GRANTED) {
18485            String msg = "Permission Denial: switchUser() from pid="
18486                    + Binder.getCallingPid()
18487                    + ", uid=" + Binder.getCallingUid()
18488                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18489            Slog.w(TAG, msg);
18490            throw new SecurityException(msg);
18491        }
18492
18493        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
18494
18495        final long ident = Binder.clearCallingIdentity();
18496        try {
18497            synchronized (this) {
18498                final int oldUserId = mCurrentUserId;
18499                if (oldUserId == userId) {
18500                    return true;
18501                }
18502
18503                mStackSupervisor.setLockTaskModeLocked(null, false);
18504
18505                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18506                if (userInfo == null) {
18507                    Slog.w(TAG, "No user info for user #" + userId);
18508                    return false;
18509                }
18510                if (foreground && userInfo.isManagedProfile()) {
18511                    Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18512                    return false;
18513                }
18514
18515                if (foreground) {
18516                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
18517                            R.anim.screen_user_enter);
18518                }
18519
18520                boolean needStart = false;
18521
18522                // If the user we are switching to is not currently started, then
18523                // we need to start it now.
18524                if (mStartedUsers.get(userId) == null) {
18525                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
18526                    updateStartedUserArrayLocked();
18527                    needStart = true;
18528                }
18529
18530                final Integer userIdInt = Integer.valueOf(userId);
18531                mUserLru.remove(userIdInt);
18532                mUserLru.add(userIdInt);
18533
18534                if (foreground) {
18535                    mCurrentUserId = userId;
18536                    mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up
18537                    updateCurrentProfileIdsLocked();
18538                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
18539                    // Once the internal notion of the active user has switched, we lock the device
18540                    // with the option to show the user switcher on the keyguard.
18541                    mWindowManager.lockNow(null);
18542                } else {
18543                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
18544                    updateCurrentProfileIdsLocked();
18545                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
18546                    mUserLru.remove(currentUserIdInt);
18547                    mUserLru.add(currentUserIdInt);
18548                }
18549
18550                final UserStartedState uss = mStartedUsers.get(userId);
18551
18552                // Make sure user is in the started state.  If it is currently
18553                // stopping, we need to knock that off.
18554                if (uss.mState == UserStartedState.STATE_STOPPING) {
18555                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
18556                    // so we can just fairly silently bring the user back from
18557                    // the almost-dead.
18558                    uss.mState = UserStartedState.STATE_RUNNING;
18559                    updateStartedUserArrayLocked();
18560                    needStart = true;
18561                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
18562                    // This means ACTION_SHUTDOWN has been sent, so we will
18563                    // need to treat this as a new boot of the user.
18564                    uss.mState = UserStartedState.STATE_BOOTING;
18565                    updateStartedUserArrayLocked();
18566                    needStart = true;
18567                }
18568
18569                if (uss.mState == UserStartedState.STATE_BOOTING) {
18570                    // Booting up a new user, need to tell system services about it.
18571                    // Note that this is on the same handler as scheduling of broadcasts,
18572                    // which is important because it needs to go first.
18573                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
18574                }
18575
18576                if (foreground) {
18577                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
18578                            oldUserId));
18579                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
18580                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18581                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
18582                            oldUserId, userId, uss));
18583                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
18584                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
18585                }
18586
18587                if (needStart) {
18588                    // Send USER_STARTED broadcast
18589                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
18590                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18591                            | Intent.FLAG_RECEIVER_FOREGROUND);
18592                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18593                    broadcastIntentLocked(null, null, intent,
18594                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18595                            false, false, MY_PID, Process.SYSTEM_UID, userId);
18596                }
18597
18598                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
18599                    if (userId != UserHandle.USER_OWNER) {
18600                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
18601                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18602                        broadcastIntentLocked(null, null, intent, null,
18603                                new IIntentReceiver.Stub() {
18604                                    public void performReceive(Intent intent, int resultCode,
18605                                            String data, Bundle extras, boolean ordered,
18606                                            boolean sticky, int sendingUser) {
18607                                        onUserInitialized(uss, foreground, oldUserId, userId);
18608                                    }
18609                                }, 0, null, null, null, AppOpsManager.OP_NONE,
18610                                true, false, MY_PID, Process.SYSTEM_UID,
18611                                userId);
18612                        uss.initializing = true;
18613                    } else {
18614                        getUserManagerLocked().makeInitialized(userInfo.id);
18615                    }
18616                }
18617
18618                if (foreground) {
18619                    if (!uss.initializing) {
18620                        moveUserToForeground(uss, oldUserId, userId);
18621                    }
18622                } else {
18623                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
18624                }
18625
18626                if (needStart) {
18627                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
18628                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18629                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18630                    broadcastIntentLocked(null, null, intent,
18631                            null, new IIntentReceiver.Stub() {
18632                                @Override
18633                                public void performReceive(Intent intent, int resultCode, String data,
18634                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
18635                                        throws RemoteException {
18636                                }
18637                            }, 0, null, null,
18638                            INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
18639                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18640                }
18641            }
18642        } finally {
18643            Binder.restoreCallingIdentity(ident);
18644        }
18645
18646        return true;
18647    }
18648
18649    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
18650        long ident = Binder.clearCallingIdentity();
18651        try {
18652            Intent intent;
18653            if (oldUserId >= 0) {
18654                // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
18655                List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
18656                int count = profiles.size();
18657                for (int i = 0; i < count; i++) {
18658                    int profileUserId = profiles.get(i).id;
18659                    intent = new Intent(Intent.ACTION_USER_BACKGROUND);
18660                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18661                            | Intent.FLAG_RECEIVER_FOREGROUND);
18662                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18663                    broadcastIntentLocked(null, null, intent,
18664                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18665                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18666                }
18667            }
18668            if (newUserId >= 0) {
18669                // Send USER_FOREGROUND broadcast to all profiles of the incoming user
18670                List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
18671                int count = profiles.size();
18672                for (int i = 0; i < count; i++) {
18673                    int profileUserId = profiles.get(i).id;
18674                    intent = new Intent(Intent.ACTION_USER_FOREGROUND);
18675                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18676                            | Intent.FLAG_RECEIVER_FOREGROUND);
18677                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18678                    broadcastIntentLocked(null, null, intent,
18679                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18680                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18681                }
18682                intent = new Intent(Intent.ACTION_USER_SWITCHED);
18683                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18684                        | Intent.FLAG_RECEIVER_FOREGROUND);
18685                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
18686                broadcastIntentLocked(null, null, intent,
18687                        null, null, 0, null, null,
18688                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
18689                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18690            }
18691        } finally {
18692            Binder.restoreCallingIdentity(ident);
18693        }
18694    }
18695
18696    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
18697            final int newUserId) {
18698        final int N = mUserSwitchObservers.beginBroadcast();
18699        if (N > 0) {
18700            final IRemoteCallback callback = new IRemoteCallback.Stub() {
18701                int mCount = 0;
18702                @Override
18703                public void sendResult(Bundle data) throws RemoteException {
18704                    synchronized (ActivityManagerService.this) {
18705                        if (mCurUserSwitchCallback == this) {
18706                            mCount++;
18707                            if (mCount == N) {
18708                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18709                            }
18710                        }
18711                    }
18712                }
18713            };
18714            synchronized (this) {
18715                uss.switching = true;
18716                mCurUserSwitchCallback = callback;
18717            }
18718            for (int i=0; i<N; i++) {
18719                try {
18720                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
18721                            newUserId, callback);
18722                } catch (RemoteException e) {
18723                }
18724            }
18725        } else {
18726            synchronized (this) {
18727                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18728            }
18729        }
18730        mUserSwitchObservers.finishBroadcast();
18731    }
18732
18733    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18734        synchronized (this) {
18735            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
18736            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18737        }
18738    }
18739
18740    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
18741        mCurUserSwitchCallback = null;
18742        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18743        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
18744                oldUserId, newUserId, uss));
18745    }
18746
18747    void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) {
18748        synchronized (this) {
18749            if (foreground) {
18750                moveUserToForeground(uss, oldUserId, newUserId);
18751            }
18752        }
18753
18754        completeSwitchAndInitalize(uss, newUserId, true, false);
18755    }
18756
18757    void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) {
18758        boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss);
18759        if (homeInFront) {
18760            startHomeActivityLocked(newUserId);
18761        } else {
18762            mStackSupervisor.resumeTopActivitiesLocked();
18763        }
18764        EventLogTags.writeAmSwitchUser(newUserId);
18765        getUserManagerLocked().userForeground(newUserId);
18766        sendUserSwitchBroadcastsLocked(oldUserId, newUserId);
18767    }
18768
18769    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18770        completeSwitchAndInitalize(uss, newUserId, false, true);
18771    }
18772
18773    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
18774            boolean clearInitializing, boolean clearSwitching) {
18775        boolean unfrozen = false;
18776        synchronized (this) {
18777            if (clearInitializing) {
18778                uss.initializing = false;
18779                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
18780            }
18781            if (clearSwitching) {
18782                uss.switching = false;
18783            }
18784            if (!uss.switching && !uss.initializing) {
18785                mWindowManager.stopFreezingScreen();
18786                unfrozen = true;
18787            }
18788        }
18789        if (unfrozen) {
18790            final int N = mUserSwitchObservers.beginBroadcast();
18791            for (int i=0; i<N; i++) {
18792                try {
18793                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
18794                } catch (RemoteException e) {
18795                }
18796            }
18797            mUserSwitchObservers.finishBroadcast();
18798        }
18799    }
18800
18801    void scheduleStartProfilesLocked() {
18802        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
18803            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
18804                    DateUtils.SECOND_IN_MILLIS);
18805        }
18806    }
18807
18808    void startProfilesLocked() {
18809        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
18810        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18811                mCurrentUserId, false /* enabledOnly */);
18812        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
18813        for (UserInfo user : profiles) {
18814            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
18815                    && user.id != mCurrentUserId) {
18816                toStart.add(user);
18817            }
18818        }
18819        final int n = toStart.size();
18820        int i = 0;
18821        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
18822            startUserInBackground(toStart.get(i).id);
18823        }
18824        if (i < n) {
18825            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
18826        }
18827    }
18828
18829    void finishUserBoot(UserStartedState uss) {
18830        synchronized (this) {
18831            if (uss.mState == UserStartedState.STATE_BOOTING
18832                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
18833                uss.mState = UserStartedState.STATE_RUNNING;
18834                final int userId = uss.mHandle.getIdentifier();
18835                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
18836                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18837                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
18838                broadcastIntentLocked(null, null, intent,
18839                        null, null, 0, null, null,
18840                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
18841                        true, false, MY_PID, Process.SYSTEM_UID, userId);
18842            }
18843        }
18844    }
18845
18846    void finishUserSwitch(UserStartedState uss) {
18847        synchronized (this) {
18848            finishUserBoot(uss);
18849
18850            startProfilesLocked();
18851
18852            int num = mUserLru.size();
18853            int i = 0;
18854            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
18855                Integer oldUserId = mUserLru.get(i);
18856                UserStartedState oldUss = mStartedUsers.get(oldUserId);
18857                if (oldUss == null) {
18858                    // Shouldn't happen, but be sane if it does.
18859                    mUserLru.remove(i);
18860                    num--;
18861                    continue;
18862                }
18863                if (oldUss.mState == UserStartedState.STATE_STOPPING
18864                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
18865                    // This user is already stopping, doesn't count.
18866                    num--;
18867                    i++;
18868                    continue;
18869                }
18870                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
18871                    // Owner and current can't be stopped, but count as running.
18872                    i++;
18873                    continue;
18874                }
18875                // This is a user to be stopped.
18876                stopUserLocked(oldUserId, null);
18877                num--;
18878                i++;
18879            }
18880        }
18881    }
18882
18883    @Override
18884    public int stopUser(final int userId, final IStopUserCallback callback) {
18885        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18886                != PackageManager.PERMISSION_GRANTED) {
18887            String msg = "Permission Denial: switchUser() from pid="
18888                    + Binder.getCallingPid()
18889                    + ", uid=" + Binder.getCallingUid()
18890                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18891            Slog.w(TAG, msg);
18892            throw new SecurityException(msg);
18893        }
18894        if (userId <= 0) {
18895            throw new IllegalArgumentException("Can't stop primary user " + userId);
18896        }
18897        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
18898        synchronized (this) {
18899            return stopUserLocked(userId, callback);
18900        }
18901    }
18902
18903    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
18904        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
18905        if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) {
18906            return ActivityManager.USER_OP_IS_CURRENT;
18907        }
18908
18909        final UserStartedState uss = mStartedUsers.get(userId);
18910        if (uss == null) {
18911            // User is not started, nothing to do...  but we do need to
18912            // callback if requested.
18913            if (callback != null) {
18914                mHandler.post(new Runnable() {
18915                    @Override
18916                    public void run() {
18917                        try {
18918                            callback.userStopped(userId);
18919                        } catch (RemoteException e) {
18920                        }
18921                    }
18922                });
18923            }
18924            return ActivityManager.USER_OP_SUCCESS;
18925        }
18926
18927        if (callback != null) {
18928            uss.mStopCallbacks.add(callback);
18929        }
18930
18931        if (uss.mState != UserStartedState.STATE_STOPPING
18932                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18933            uss.mState = UserStartedState.STATE_STOPPING;
18934            updateStartedUserArrayLocked();
18935
18936            long ident = Binder.clearCallingIdentity();
18937            try {
18938                // We are going to broadcast ACTION_USER_STOPPING and then
18939                // once that is done send a final ACTION_SHUTDOWN and then
18940                // stop the user.
18941                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
18942                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18943                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18944                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
18945                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
18946                // This is the result receiver for the final shutdown broadcast.
18947                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
18948                    @Override
18949                    public void performReceive(Intent intent, int resultCode, String data,
18950                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
18951                        finishUserStop(uss);
18952                    }
18953                };
18954                // This is the result receiver for the initial stopping broadcast.
18955                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
18956                    @Override
18957                    public void performReceive(Intent intent, int resultCode, String data,
18958                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
18959                        // On to the next.
18960                        synchronized (ActivityManagerService.this) {
18961                            if (uss.mState != UserStartedState.STATE_STOPPING) {
18962                                // Whoops, we are being started back up.  Abort, abort!
18963                                return;
18964                            }
18965                            uss.mState = UserStartedState.STATE_SHUTDOWN;
18966                        }
18967                        mBatteryStatsService.noteEvent(
18968                                BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
18969                                Integer.toString(userId), userId);
18970                        mSystemServiceManager.stopUser(userId);
18971                        broadcastIntentLocked(null, null, shutdownIntent,
18972                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
18973                                true, false, MY_PID, Process.SYSTEM_UID, userId);
18974                    }
18975                };
18976                // Kick things off.
18977                broadcastIntentLocked(null, null, stoppingIntent,
18978                        null, stoppingReceiver, 0, null, null,
18979                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
18980                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18981            } finally {
18982                Binder.restoreCallingIdentity(ident);
18983            }
18984        }
18985
18986        return ActivityManager.USER_OP_SUCCESS;
18987    }
18988
18989    void finishUserStop(UserStartedState uss) {
18990        final int userId = uss.mHandle.getIdentifier();
18991        boolean stopped;
18992        ArrayList<IStopUserCallback> callbacks;
18993        synchronized (this) {
18994            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
18995            if (mStartedUsers.get(userId) != uss) {
18996                stopped = false;
18997            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
18998                stopped = false;
18999            } else {
19000                stopped = true;
19001                // User can no longer run.
19002                mStartedUsers.remove(userId);
19003                mUserLru.remove(Integer.valueOf(userId));
19004                updateStartedUserArrayLocked();
19005
19006                // Clean up all state and processes associated with the user.
19007                // Kill all the processes for the user.
19008                forceStopUserLocked(userId, "finish user");
19009            }
19010
19011            // Explicitly remove the old information in mRecentTasks.
19012            removeRecentTasksForUserLocked(userId);
19013        }
19014
19015        for (int i=0; i<callbacks.size(); i++) {
19016            try {
19017                if (stopped) callbacks.get(i).userStopped(userId);
19018                else callbacks.get(i).userStopAborted(userId);
19019            } catch (RemoteException e) {
19020            }
19021        }
19022
19023        if (stopped) {
19024            mSystemServiceManager.cleanupUser(userId);
19025            synchronized (this) {
19026                mStackSupervisor.removeUserLocked(userId);
19027            }
19028        }
19029    }
19030
19031    @Override
19032    public UserInfo getCurrentUser() {
19033        if ((checkCallingPermission(INTERACT_ACROSS_USERS)
19034                != PackageManager.PERMISSION_GRANTED) && (
19035                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
19036                != PackageManager.PERMISSION_GRANTED)) {
19037            String msg = "Permission Denial: getCurrentUser() from pid="
19038                    + Binder.getCallingPid()
19039                    + ", uid=" + Binder.getCallingUid()
19040                    + " requires " + INTERACT_ACROSS_USERS;
19041            Slog.w(TAG, msg);
19042            throw new SecurityException(msg);
19043        }
19044        synchronized (this) {
19045            int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
19046            return getUserManagerLocked().getUserInfo(userId);
19047        }
19048    }
19049
19050    int getCurrentUserIdLocked() {
19051        return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
19052    }
19053
19054    @Override
19055    public boolean isUserRunning(int userId, boolean orStopped) {
19056        if (checkCallingPermission(INTERACT_ACROSS_USERS)
19057                != PackageManager.PERMISSION_GRANTED) {
19058            String msg = "Permission Denial: isUserRunning() from pid="
19059                    + Binder.getCallingPid()
19060                    + ", uid=" + Binder.getCallingUid()
19061                    + " requires " + INTERACT_ACROSS_USERS;
19062            Slog.w(TAG, msg);
19063            throw new SecurityException(msg);
19064        }
19065        synchronized (this) {
19066            return isUserRunningLocked(userId, orStopped);
19067        }
19068    }
19069
19070    boolean isUserRunningLocked(int userId, boolean orStopped) {
19071        UserStartedState state = mStartedUsers.get(userId);
19072        if (state == null) {
19073            return false;
19074        }
19075        if (orStopped) {
19076            return true;
19077        }
19078        return state.mState != UserStartedState.STATE_STOPPING
19079                && state.mState != UserStartedState.STATE_SHUTDOWN;
19080    }
19081
19082    @Override
19083    public int[] getRunningUserIds() {
19084        if (checkCallingPermission(INTERACT_ACROSS_USERS)
19085                != PackageManager.PERMISSION_GRANTED) {
19086            String msg = "Permission Denial: isUserRunning() from pid="
19087                    + Binder.getCallingPid()
19088                    + ", uid=" + Binder.getCallingUid()
19089                    + " requires " + INTERACT_ACROSS_USERS;
19090            Slog.w(TAG, msg);
19091            throw new SecurityException(msg);
19092        }
19093        synchronized (this) {
19094            return mStartedUserArray;
19095        }
19096    }
19097
19098    private void updateStartedUserArrayLocked() {
19099        int num = 0;
19100        for (int i=0; i<mStartedUsers.size();  i++) {
19101            UserStartedState uss = mStartedUsers.valueAt(i);
19102            // This list does not include stopping users.
19103            if (uss.mState != UserStartedState.STATE_STOPPING
19104                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
19105                num++;
19106            }
19107        }
19108        mStartedUserArray = new int[num];
19109        num = 0;
19110        for (int i=0; i<mStartedUsers.size();  i++) {
19111            UserStartedState uss = mStartedUsers.valueAt(i);
19112            if (uss.mState != UserStartedState.STATE_STOPPING
19113                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
19114                mStartedUserArray[num] = mStartedUsers.keyAt(i);
19115                num++;
19116            }
19117        }
19118    }
19119
19120    @Override
19121    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
19122        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
19123                != PackageManager.PERMISSION_GRANTED) {
19124            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
19125                    + Binder.getCallingPid()
19126                    + ", uid=" + Binder.getCallingUid()
19127                    + " requires " + INTERACT_ACROSS_USERS_FULL;
19128            Slog.w(TAG, msg);
19129            throw new SecurityException(msg);
19130        }
19131
19132        mUserSwitchObservers.register(observer);
19133    }
19134
19135    @Override
19136    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
19137        mUserSwitchObservers.unregister(observer);
19138    }
19139
19140    private boolean userExists(int userId) {
19141        if (userId == 0) {
19142            return true;
19143        }
19144        UserManagerService ums = getUserManagerLocked();
19145        return ums != null ? (ums.getUserInfo(userId) != null) : false;
19146    }
19147
19148    int[] getUsersLocked() {
19149        UserManagerService ums = getUserManagerLocked();
19150        return ums != null ? ums.getUserIds() : new int[] { 0 };
19151    }
19152
19153    UserManagerService getUserManagerLocked() {
19154        if (mUserManager == null) {
19155            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
19156            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
19157        }
19158        return mUserManager;
19159    }
19160
19161    private int applyUserId(int uid, int userId) {
19162        return UserHandle.getUid(userId, uid);
19163    }
19164
19165    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
19166        if (info == null) return null;
19167        ApplicationInfo newInfo = new ApplicationInfo(info);
19168        newInfo.uid = applyUserId(info.uid, userId);
19169        newInfo.dataDir = USER_DATA_DIR + userId + "/"
19170                + info.packageName;
19171        return newInfo;
19172    }
19173
19174    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
19175        if (aInfo == null
19176                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
19177            return aInfo;
19178        }
19179
19180        ActivityInfo info = new ActivityInfo(aInfo);
19181        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
19182        return info;
19183    }
19184
19185    private final class LocalService extends ActivityManagerInternal {
19186        @Override
19187        public void goingToSleep() {
19188            ActivityManagerService.this.goingToSleep();
19189        }
19190
19191        @Override
19192        public void wakingUp() {
19193            ActivityManagerService.this.wakingUp();
19194        }
19195
19196        @Override
19197        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
19198                String processName, String abiOverride, int uid, Runnable crashHandler) {
19199            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
19200                    processName, abiOverride, uid, crashHandler);
19201        }
19202    }
19203
19204    /**
19205     * An implementation of IAppTask, that allows an app to manage its own tasks via
19206     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
19207     * only the process that calls getAppTasks() can call the AppTask methods.
19208     */
19209    class AppTaskImpl extends IAppTask.Stub {
19210        private int mTaskId;
19211        private int mCallingUid;
19212
19213        public AppTaskImpl(int taskId, int callingUid) {
19214            mTaskId = taskId;
19215            mCallingUid = callingUid;
19216        }
19217
19218        private void checkCaller() {
19219            if (mCallingUid != Binder.getCallingUid()) {
19220                throw new SecurityException("Caller " + mCallingUid
19221                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
19222            }
19223        }
19224
19225        @Override
19226        public void finishAndRemoveTask() {
19227            checkCaller();
19228
19229            synchronized (ActivityManagerService.this) {
19230                long origId = Binder.clearCallingIdentity();
19231                try {
19232                    if (!removeTaskByIdLocked(mTaskId, false)) {
19233                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19234                    }
19235                } finally {
19236                    Binder.restoreCallingIdentity(origId);
19237                }
19238            }
19239        }
19240
19241        @Override
19242        public ActivityManager.RecentTaskInfo getTaskInfo() {
19243            checkCaller();
19244
19245            synchronized (ActivityManagerService.this) {
19246                long origId = Binder.clearCallingIdentity();
19247                try {
19248                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
19249                    if (tr == null) {
19250                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19251                    }
19252                    return createRecentTaskInfoFromTaskRecord(tr);
19253                } finally {
19254                    Binder.restoreCallingIdentity(origId);
19255                }
19256            }
19257        }
19258
19259        @Override
19260        public void moveToFront() {
19261            checkCaller();
19262
19263            final TaskRecord tr;
19264            synchronized (ActivityManagerService.this) {
19265                tr = recentTaskForIdLocked(mTaskId);
19266                if (tr == null) {
19267                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19268                }
19269                if (tr.getRootActivity() != null) {
19270                    moveTaskToFrontLocked(tr.taskId, 0, null);
19271                    return;
19272                }
19273            }
19274
19275            startActivityFromRecentsInner(tr.taskId, null);
19276        }
19277
19278        @Override
19279        public int startActivity(IBinder whoThread, String callingPackage,
19280                Intent intent, String resolvedType, Bundle options) {
19281            checkCaller();
19282
19283            int callingUser = UserHandle.getCallingUserId();
19284            TaskRecord tr;
19285            IApplicationThread appThread;
19286            synchronized (ActivityManagerService.this) {
19287                tr = recentTaskForIdLocked(mTaskId);
19288                if (tr == null) {
19289                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19290                }
19291                appThread = ApplicationThreadNative.asInterface(whoThread);
19292                if (appThread == null) {
19293                    throw new IllegalArgumentException("Bad app thread " + appThread);
19294                }
19295            }
19296            return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent,
19297                    resolvedType, null, null, null, null, 0, 0, null, null,
19298                    null, options, callingUser, null, tr);
19299        }
19300
19301        @Override
19302        public void setExcludeFromRecents(boolean exclude) {
19303            checkCaller();
19304
19305            synchronized (ActivityManagerService.this) {
19306                long origId = Binder.clearCallingIdentity();
19307                try {
19308                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
19309                    if (tr == null) {
19310                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19311                    }
19312                    Intent intent = tr.getBaseIntent();
19313                    if (exclude) {
19314                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
19315                    } else {
19316                        intent.setFlags(intent.getFlags()
19317                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
19318                    }
19319                } finally {
19320                    Binder.restoreCallingIdentity(origId);
19321                }
19322            }
19323        }
19324    }
19325}
19326