ActivityManagerService.java revision d31c16457a7360bc892d71c308c7ab76cdb45af1
1/*
2 * Copyright (C) 2006-2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.am;
18
19import static android.Manifest.permission.INTERACT_ACROSS_USERS;
20import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
21import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
22import static android.content.pm.PackageManager.PERMISSION_GRANTED;
23import static com.android.internal.util.XmlUtils.readBooleanAttribute;
24import static com.android.internal.util.XmlUtils.readIntAttribute;
25import static com.android.internal.util.XmlUtils.readLongAttribute;
26import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
27import static com.android.internal.util.XmlUtils.writeIntAttribute;
28import static com.android.internal.util.XmlUtils.writeLongAttribute;
29import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST;
30import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
31import static org.xmlpull.v1.XmlPullParser.START_TAG;
32import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
33import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
34
35import android.Manifest;
36import android.app.AppOpsManager;
37import android.app.ApplicationThreadNative;
38import android.app.IActivityContainer;
39import android.app.IActivityContainerCallback;
40import android.app.IAppTask;
41import android.app.ITaskStackListener;
42import android.app.ProfilerInfo;
43import android.app.admin.DevicePolicyManager;
44import android.app.usage.UsageEvents;
45import android.app.usage.UsageStatsManagerInternal;
46import android.appwidget.AppWidgetManager;
47import android.content.res.Resources;
48import android.graphics.Bitmap;
49import android.graphics.Point;
50import android.graphics.Rect;
51import android.os.BatteryStats;
52import android.os.PersistableBundle;
53import android.os.storage.IMountService;
54import android.os.storage.StorageManager;
55import android.service.voice.IVoiceInteractionSession;
56import android.util.ArrayMap;
57import android.util.ArraySet;
58import android.util.SparseIntArray;
59
60import com.android.internal.R;
61import com.android.internal.annotations.GuardedBy;
62import com.android.internal.app.IAppOpsService;
63import com.android.internal.app.IVoiceInteractor;
64import com.android.internal.app.ProcessMap;
65import com.android.internal.app.ProcessStats;
66import com.android.internal.os.BackgroundThread;
67import com.android.internal.os.BatteryStatsImpl;
68import com.android.internal.os.ProcessCpuTracker;
69import com.android.internal.os.TransferPipe;
70import com.android.internal.os.Zygote;
71import com.android.internal.util.FastPrintWriter;
72import com.android.internal.util.FastXmlSerializer;
73import com.android.internal.util.MemInfoReader;
74import com.android.internal.util.Preconditions;
75import com.android.server.AppOpsService;
76import com.android.server.AttributeCache;
77import com.android.server.IntentResolver;
78import com.android.server.LocalServices;
79import com.android.server.ServiceThread;
80import com.android.server.SystemService;
81import com.android.server.SystemServiceManager;
82import com.android.server.Watchdog;
83import com.android.server.am.ActivityStack.ActivityState;
84import com.android.server.firewall.IntentFirewall;
85import com.android.server.pm.Installer;
86import com.android.server.pm.UserManagerService;
87import com.android.server.statusbar.StatusBarManagerInternal;
88import com.android.server.wm.AppTransition;
89import com.android.server.wm.WindowManagerService;
90import com.google.android.collect.Lists;
91import com.google.android.collect.Maps;
92
93import libcore.io.IoUtils;
94
95import org.xmlpull.v1.XmlPullParser;
96import org.xmlpull.v1.XmlPullParserException;
97import org.xmlpull.v1.XmlSerializer;
98
99import android.app.Activity;
100import android.app.ActivityManager;
101import android.app.ActivityManager.RunningTaskInfo;
102import android.app.ActivityManager.StackInfo;
103import android.app.ActivityManagerInternal;
104import android.app.ActivityManagerNative;
105import android.app.ActivityOptions;
106import android.app.ActivityThread;
107import android.app.AlertDialog;
108import android.app.AppGlobals;
109import android.app.ApplicationErrorReport;
110import android.app.Dialog;
111import android.app.IActivityController;
112import android.app.IApplicationThread;
113import android.app.IInstrumentationWatcher;
114import android.app.INotificationManager;
115import android.app.IProcessObserver;
116import android.app.IServiceConnection;
117import android.app.IStopUserCallback;
118import android.app.IUiAutomationConnection;
119import android.app.IUserSwitchObserver;
120import android.app.Instrumentation;
121import android.app.Notification;
122import android.app.NotificationManager;
123import android.app.PendingIntent;
124import android.app.backup.IBackupManager;
125import android.content.ActivityNotFoundException;
126import android.content.BroadcastReceiver;
127import android.content.ClipData;
128import android.content.ComponentCallbacks2;
129import android.content.ComponentName;
130import android.content.ContentProvider;
131import android.content.ContentResolver;
132import android.content.Context;
133import android.content.DialogInterface;
134import android.content.IContentProvider;
135import android.content.IIntentReceiver;
136import android.content.IIntentSender;
137import android.content.Intent;
138import android.content.IntentFilter;
139import android.content.IntentSender;
140import android.content.pm.ActivityInfo;
141import android.content.pm.ApplicationInfo;
142import android.content.pm.ConfigurationInfo;
143import android.content.pm.IPackageDataObserver;
144import android.content.pm.IPackageManager;
145import android.content.pm.InstrumentationInfo;
146import android.content.pm.PackageInfo;
147import android.content.pm.PackageManager;
148import android.content.pm.ParceledListSlice;
149import android.content.pm.UserInfo;
150import android.content.pm.PackageManager.NameNotFoundException;
151import android.content.pm.PathPermission;
152import android.content.pm.ProviderInfo;
153import android.content.pm.ResolveInfo;
154import android.content.pm.ServiceInfo;
155import android.content.res.CompatibilityInfo;
156import android.content.res.Configuration;
157import android.net.Proxy;
158import android.net.ProxyInfo;
159import android.net.Uri;
160import android.os.Binder;
161import android.os.Build;
162import android.os.Bundle;
163import android.os.Debug;
164import android.os.DropBoxManager;
165import android.os.Environment;
166import android.os.FactoryTest;
167import android.os.FileObserver;
168import android.os.FileUtils;
169import android.os.Handler;
170import android.os.IBinder;
171import android.os.IPermissionController;
172import android.os.IRemoteCallback;
173import android.os.IUserManager;
174import android.os.Looper;
175import android.os.Message;
176import android.os.Parcel;
177import android.os.ParcelFileDescriptor;
178import android.os.PowerManagerInternal;
179import android.os.Process;
180import android.os.RemoteCallbackList;
181import android.os.RemoteException;
182import android.os.SELinux;
183import android.os.ServiceManager;
184import android.os.StrictMode;
185import android.os.SystemClock;
186import android.os.SystemProperties;
187import android.os.UpdateLock;
188import android.os.UserHandle;
189import android.os.UserManager;
190import android.provider.Settings;
191import android.text.format.DateUtils;
192import android.text.format.Time;
193import android.util.AtomicFile;
194import android.util.EventLog;
195import android.util.Log;
196import android.util.Pair;
197import android.util.PrintWriterPrinter;
198import android.util.Slog;
199import android.util.SparseArray;
200import android.util.TimeUtils;
201import android.util.Xml;
202import android.view.Gravity;
203import android.view.LayoutInflater;
204import android.view.View;
205import android.view.WindowManager;
206
207import dalvik.system.VMRuntime;
208
209import java.io.BufferedInputStream;
210import java.io.BufferedOutputStream;
211import java.io.DataInputStream;
212import java.io.DataOutputStream;
213import java.io.File;
214import java.io.FileDescriptor;
215import java.io.FileInputStream;
216import java.io.FileNotFoundException;
217import java.io.FileOutputStream;
218import java.io.IOException;
219import java.io.InputStreamReader;
220import java.io.PrintWriter;
221import java.io.StringWriter;
222import java.lang.ref.WeakReference;
223import java.util.ArrayList;
224import java.util.Arrays;
225import java.util.Collections;
226import java.util.Comparator;
227import java.util.HashMap;
228import java.util.HashSet;
229import java.util.Iterator;
230import java.util.List;
231import java.util.Locale;
232import java.util.Map;
233import java.util.Set;
234import java.util.concurrent.atomic.AtomicBoolean;
235import java.util.concurrent.atomic.AtomicLong;
236
237public final class ActivityManagerService extends ActivityManagerNative
238        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
239
240    private static final String USER_DATA_DIR = "/data/user/";
241    // File that stores last updated system version and called preboot receivers
242    static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat";
243
244    static final String TAG = "ActivityManager";
245    static final String TAG_MU = "ActivityManagerServiceMU";
246    static final boolean DEBUG = false;
247    static final boolean localLOGV = DEBUG;
248    static final boolean DEBUG_BACKUP = localLOGV || false;
249    static final boolean DEBUG_BROADCAST = localLOGV || false;
250    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
251    static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
252    static final boolean DEBUG_CLEANUP = localLOGV || false;
253    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
254    static final boolean DEBUG_FOCUS = false;
255    static final boolean DEBUG_IMMERSIVE = localLOGV || false;
256    static final boolean DEBUG_MU = localLOGV || false;
257    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
258    static final boolean DEBUG_LRU = localLOGV || false;
259    static final boolean DEBUG_PAUSE = localLOGV || false;
260    static final boolean DEBUG_POWER = localLOGV || false;
261    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
262    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
263    static final boolean DEBUG_PROCESSES = localLOGV || false;
264    static final boolean DEBUG_PROVIDER = localLOGV || false;
265    static final boolean DEBUG_RESULTS = localLOGV || false;
266    static final boolean DEBUG_SERVICE = localLOGV || false;
267    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
268    static final boolean DEBUG_STACK = localLOGV || false;
269    static final boolean DEBUG_SWITCH = localLOGV || false;
270    static final boolean DEBUG_TASKS = localLOGV || false;
271    static final boolean DEBUG_THUMBNAILS = localLOGV || false;
272    static final boolean DEBUG_TRANSITION = localLOGV || false;
273    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
274    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
275    static final boolean DEBUG_VISBILITY = localLOGV || false;
276    static final boolean DEBUG_PSS = localLOGV || false;
277    static final boolean DEBUG_LOCKSCREEN = localLOGV || false;
278    static final boolean DEBUG_RECENTS = localLOGV || false;
279    static final boolean VALIDATE_TOKENS = false;
280    static final boolean SHOW_ACTIVITY_START_TIME = true;
281
282    // Control over CPU and battery monitoring.
283    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
284    static final boolean MONITOR_CPU_USAGE = true;
285    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
286    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
287    static final boolean MONITOR_THREAD_CPU_USAGE = false;
288
289    // The flags that are set for all calls we make to the package manager.
290    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
291
292    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
293
294    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
295
296    // 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    // Delay in notifying task stack change listeners (in millis)
373    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 1000;
374
375    /** All system services */
376    SystemServiceManager mSystemServiceManager;
377
378    private Installer mInstaller;
379
380    /** Run all ActivityStacks through this */
381    ActivityStackSupervisor mStackSupervisor;
382
383    /** Task stack change listeners. */
384    private RemoteCallbackList<ITaskStackListener> mTaskStackListeners =
385            new RemoteCallbackList<ITaskStackListener>();
386
387    public IntentFirewall mIntentFirewall;
388
389    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
390    // default actuion automatically.  Important for devices without direct input
391    // devices.
392    private boolean mShowDialogs = true;
393
394    BroadcastQueue mFgBroadcastQueue;
395    BroadcastQueue mBgBroadcastQueue;
396    // Convenient for easy iteration over the queues. Foreground is first
397    // so that dispatch of foreground broadcasts gets precedence.
398    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
399
400    BroadcastQueue broadcastQueueForIntent(Intent intent) {
401        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
402        if (DEBUG_BACKGROUND_BROADCAST) {
403            Slog.i(TAG, "Broadcast intent " + intent + " on "
404                    + (isFg ? "foreground" : "background")
405                    + " queue");
406        }
407        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
408    }
409
410    /**
411     * Activity we have told the window manager to have key focus.
412     */
413    ActivityRecord mFocusedActivity = null;
414
415    /**
416     * List of intents that were used to start the most recent tasks.
417     */
418    private final RecentTasks mRecentTasks;
419
420    /**
421     * For addAppTask: cached of the last activity component that was added.
422     */
423    ComponentName mLastAddedTaskComponent;
424
425    /**
426     * For addAppTask: cached of the last activity uid that was added.
427     */
428    int mLastAddedTaskUid;
429
430    /**
431     * For addAppTask: cached of the last ActivityInfo that was added.
432     */
433    ActivityInfo mLastAddedTaskActivity;
434
435    public class PendingAssistExtras extends Binder implements Runnable {
436        public final ActivityRecord activity;
437        public final Bundle extras;
438        public final Intent intent;
439        public final String hint;
440        public final int userHandle;
441        public boolean haveResult = false;
442        public Bundle result = null;
443        public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
444                String _hint, int _userHandle) {
445            activity = _activity;
446            extras = _extras;
447            intent = _intent;
448            hint = _hint;
449            userHandle = _userHandle;
450        }
451        @Override
452        public void run() {
453            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
454            synchronized (this) {
455                haveResult = true;
456                notifyAll();
457            }
458        }
459    }
460
461    final ArrayList<PendingAssistExtras> mPendingAssistExtras
462            = new ArrayList<PendingAssistExtras>();
463
464    /**
465     * Process management.
466     */
467    final ProcessList mProcessList = new ProcessList();
468
469    /**
470     * All of the applications we currently have running organized by name.
471     * The keys are strings of the application package name (as
472     * returned by the package manager), and the keys are ApplicationRecord
473     * objects.
474     */
475    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
476
477    /**
478     * Tracking long-term execution of processes to look for abuse and other
479     * bad app behavior.
480     */
481    final ProcessStatsService mProcessStats;
482
483    /**
484     * The currently running isolated processes.
485     */
486    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
487
488    /**
489     * Counter for assigning isolated process uids, to avoid frequently reusing the
490     * same ones.
491     */
492    int mNextIsolatedProcessUid = 0;
493
494    /**
495     * The currently running heavy-weight process, if any.
496     */
497    ProcessRecord mHeavyWeightProcess = null;
498
499    /**
500     * The last time that various processes have crashed.
501     */
502    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
503
504    /**
505     * Information about a process that is currently marked as bad.
506     */
507    static final class BadProcessInfo {
508        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
509            this.time = time;
510            this.shortMsg = shortMsg;
511            this.longMsg = longMsg;
512            this.stack = stack;
513        }
514
515        final long time;
516        final String shortMsg;
517        final String longMsg;
518        final String stack;
519    }
520
521    /**
522     * Set of applications that we consider to be bad, and will reject
523     * incoming broadcasts from (which the user has no control over).
524     * Processes are added to this set when they have crashed twice within
525     * a minimum amount of time; they are removed from it when they are
526     * later restarted (hopefully due to some user action).  The value is the
527     * time it was added to the list.
528     */
529    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
530
531    /**
532     * All of the processes we currently have running organized by pid.
533     * The keys are the pid running the application.
534     *
535     * <p>NOTE: This object is protected by its own lock, NOT the global
536     * activity manager lock!
537     */
538    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
539
540    /**
541     * All of the processes that have been forced to be foreground.  The key
542     * is the pid of the caller who requested it (we hold a death
543     * link on it).
544     */
545    abstract class ForegroundToken implements IBinder.DeathRecipient {
546        int pid;
547        IBinder token;
548    }
549    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
550
551    /**
552     * List of records for processes that someone had tried to start before the
553     * system was ready.  We don't start them at that point, but ensure they
554     * are started by the time booting is complete.
555     */
556    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
557
558    /**
559     * List of persistent applications that are in the process
560     * of being started.
561     */
562    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
563
564    /**
565     * Processes that are being forcibly torn down.
566     */
567    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
568
569    /**
570     * List of running applications, sorted by recent usage.
571     * The first entry in the list is the least recently used.
572     */
573    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
574
575    /**
576     * Where in mLruProcesses that the processes hosting activities start.
577     */
578    int mLruProcessActivityStart = 0;
579
580    /**
581     * Where in mLruProcesses that the processes hosting services start.
582     * This is after (lower index) than mLruProcessesActivityStart.
583     */
584    int mLruProcessServiceStart = 0;
585
586    /**
587     * List of processes that should gc as soon as things are idle.
588     */
589    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
590
591    /**
592     * Processes we want to collect PSS data from.
593     */
594    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
595
596    /**
597     * Last time we requested PSS data of all processes.
598     */
599    long mLastFullPssTime = SystemClock.uptimeMillis();
600
601    /**
602     * If set, the next time we collect PSS data we should do a full collection
603     * with data from native processes and the kernel.
604     */
605    boolean mFullPssPending = false;
606
607    /**
608     * This is the process holding what we currently consider to be
609     * the "home" activity.
610     */
611    ProcessRecord mHomeProcess;
612
613    /**
614     * This is the process holding the activity the user last visited that
615     * is in a different process from the one they are currently in.
616     */
617    ProcessRecord mPreviousProcess;
618
619    /**
620     * The time at which the previous process was last visible.
621     */
622    long mPreviousProcessVisibleTime;
623
624    /**
625     * Which uses have been started, so are allowed to run code.
626     */
627    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
628
629    /**
630     * LRU list of history of current users.  Most recently current is at the end.
631     */
632    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
633
634    /**
635     * Constant array of the users that are currently started.
636     */
637    int[] mStartedUserArray = new int[] { 0 };
638
639    /**
640     * Registered observers of the user switching mechanics.
641     */
642    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
643            = new RemoteCallbackList<IUserSwitchObserver>();
644
645    /**
646     * Currently active user switch.
647     */
648    Object mCurUserSwitchCallback;
649
650    /**
651     * Packages that the user has asked to have run in screen size
652     * compatibility mode instead of filling the screen.
653     */
654    final CompatModePackages mCompatModePackages;
655
656    /**
657     * Set of IntentSenderRecord objects that are currently active.
658     */
659    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
660            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
661
662    /**
663     * Fingerprints (hashCode()) of stack traces that we've
664     * already logged DropBox entries for.  Guarded by itself.  If
665     * something (rogue user app) forces this over
666     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
667     */
668    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
669    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
670
671    /**
672     * Strict Mode background batched logging state.
673     *
674     * The string buffer is guarded by itself, and its lock is also
675     * used to determine if another batched write is already
676     * in-flight.
677     */
678    private final StringBuilder mStrictModeBuffer = new StringBuilder();
679
680    /**
681     * Keeps track of all IIntentReceivers that have been registered for
682     * broadcasts.  Hash keys are the receiver IBinder, hash value is
683     * a ReceiverList.
684     */
685    final HashMap<IBinder, ReceiverList> mRegisteredReceivers =
686            new HashMap<IBinder, ReceiverList>();
687
688    /**
689     * Resolver for broadcast intents to registered receivers.
690     * Holds BroadcastFilter (subclass of IntentFilter).
691     */
692    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
693            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
694        @Override
695        protected boolean allowFilterResult(
696                BroadcastFilter filter, List<BroadcastFilter> dest) {
697            IBinder target = filter.receiverList.receiver.asBinder();
698            for (int i=dest.size()-1; i>=0; i--) {
699                if (dest.get(i).receiverList.receiver.asBinder() == target) {
700                    return false;
701                }
702            }
703            return true;
704        }
705
706        @Override
707        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
708            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
709                    || userId == filter.owningUserId) {
710                return super.newResult(filter, match, userId);
711            }
712            return null;
713        }
714
715        @Override
716        protected BroadcastFilter[] newArray(int size) {
717            return new BroadcastFilter[size];
718        }
719
720        @Override
721        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
722            return packageName.equals(filter.packageName);
723        }
724    };
725
726    /**
727     * State of all active sticky broadcasts per user.  Keys are the action of the
728     * sticky Intent, values are an ArrayList of all broadcasted intents with
729     * that action (which should usually be one).  The SparseArray is keyed
730     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
731     * for stickies that are sent to all users.
732     */
733    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
734            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
735
736    final ActiveServices mServices;
737
738    final static class Association {
739        final int mSourceUid;
740        final String mSourceProcess;
741        final int mTargetUid;
742        final ComponentName mTargetComponent;
743        final String mTargetProcess;
744
745        int mCount;
746        long mTime;
747
748        int mNesting;
749        long mStartTime;
750
751        Association(int sourceUid, String sourceProcess, int targetUid,
752                ComponentName targetComponent, String targetProcess) {
753            mSourceUid = sourceUid;
754            mSourceProcess = sourceProcess;
755            mTargetUid = targetUid;
756            mTargetComponent = targetComponent;
757            mTargetProcess = targetProcess;
758        }
759    }
760
761    /**
762     * When service association tracking is enabled, this is all of the associations we
763     * have seen.  Mapping is target uid -> target component -> source uid -> source process name
764     * -> association data.
765     */
766    final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
767            mAssociations = new SparseArray<>();
768    boolean mTrackingAssociations;
769
770    /**
771     * Backup/restore process management
772     */
773    String mBackupAppName = null;
774    BackupRecord mBackupTarget = null;
775
776    final ProviderMap mProviderMap;
777
778    /**
779     * List of content providers who have clients waiting for them.  The
780     * application is currently being launched and the provider will be
781     * removed from this list once it is published.
782     */
783    final ArrayList<ContentProviderRecord> mLaunchingProviders
784            = new ArrayList<ContentProviderRecord>();
785
786    /**
787     * File storing persisted {@link #mGrantedUriPermissions}.
788     */
789    private final AtomicFile mGrantFile;
790
791    /** XML constants used in {@link #mGrantFile} */
792    private static final String TAG_URI_GRANTS = "uri-grants";
793    private static final String TAG_URI_GRANT = "uri-grant";
794    private static final String ATTR_USER_HANDLE = "userHandle";
795    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
796    private static final String ATTR_TARGET_USER_ID = "targetUserId";
797    private static final String ATTR_SOURCE_PKG = "sourcePkg";
798    private static final String ATTR_TARGET_PKG = "targetPkg";
799    private static final String ATTR_URI = "uri";
800    private static final String ATTR_MODE_FLAGS = "modeFlags";
801    private static final String ATTR_CREATED_TIME = "createdTime";
802    private static final String ATTR_PREFIX = "prefix";
803
804    /**
805     * Global set of specific {@link Uri} permissions that have been granted.
806     * This optimized lookup structure maps from {@link UriPermission#targetUid}
807     * to {@link UriPermission#uri} to {@link UriPermission}.
808     */
809    @GuardedBy("this")
810    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
811            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
812
813    public static class GrantUri {
814        public final int sourceUserId;
815        public final Uri uri;
816        public boolean prefix;
817
818        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
819            this.sourceUserId = sourceUserId;
820            this.uri = uri;
821            this.prefix = prefix;
822        }
823
824        @Override
825        public int hashCode() {
826            int hashCode = 1;
827            hashCode = 31 * hashCode + sourceUserId;
828            hashCode = 31 * hashCode + uri.hashCode();
829            hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
830            return hashCode;
831        }
832
833        @Override
834        public boolean equals(Object o) {
835            if (o instanceof GrantUri) {
836                GrantUri other = (GrantUri) o;
837                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
838                        && prefix == other.prefix;
839            }
840            return false;
841        }
842
843        @Override
844        public String toString() {
845            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
846            if (prefix) result += " [prefix]";
847            return result;
848        }
849
850        public String toSafeString() {
851            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
852            if (prefix) result += " [prefix]";
853            return result;
854        }
855
856        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
857            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
858                    ContentProvider.getUriWithoutUserId(uri), false);
859        }
860    }
861
862    CoreSettingsObserver mCoreSettingsObserver;
863
864    /**
865     * Thread-local storage used to carry caller permissions over through
866     * indirect content-provider access.
867     */
868    private class Identity {
869        public final IBinder token;
870        public final int pid;
871        public final int uid;
872
873        Identity(IBinder _token, int _pid, int _uid) {
874            token = _token;
875            pid = _pid;
876            uid = _uid;
877        }
878    }
879
880    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
881
882    /**
883     * All information we have collected about the runtime performance of
884     * any user id that can impact battery performance.
885     */
886    final BatteryStatsService mBatteryStatsService;
887
888    /**
889     * Information about component usage
890     */
891    UsageStatsManagerInternal mUsageStatsService;
892
893    /**
894     * Information about and control over application operations
895     */
896    final AppOpsService mAppOpsService;
897
898    /**
899     * Save recent tasks information across reboots.
900     */
901    final TaskPersister mTaskPersister;
902
903    /**
904     * Current configuration information.  HistoryRecord objects are given
905     * a reference to this object to indicate which configuration they are
906     * currently running in, so this object must be kept immutable.
907     */
908    Configuration mConfiguration = new Configuration();
909
910    /**
911     * Current sequencing integer of the configuration, for skipping old
912     * configurations.
913     */
914    int mConfigurationSeq = 0;
915
916    /**
917     * Hardware-reported OpenGLES version.
918     */
919    final int GL_ES_VERSION;
920
921    /**
922     * List of initialization arguments to pass to all processes when binding applications to them.
923     * For example, references to the commonly used services.
924     */
925    HashMap<String, IBinder> mAppBindArgs;
926
927    /**
928     * Temporary to avoid allocations.  Protected by main lock.
929     */
930    final StringBuilder mStringBuilder = new StringBuilder(256);
931
932    /**
933     * Used to control how we initialize the service.
934     */
935    ComponentName mTopComponent;
936    String mTopAction = Intent.ACTION_MAIN;
937    String mTopData;
938    boolean mProcessesReady = false;
939    boolean mSystemReady = false;
940    boolean mBooting = false;
941    boolean mCallFinishBooting = false;
942    boolean mBootAnimationComplete = false;
943    boolean mWaitingUpdate = false;
944    boolean mDidUpdate = false;
945    boolean mOnBattery = false;
946    boolean mLaunchWarningShown = false;
947
948    Context mContext;
949
950    int mFactoryTest;
951
952    boolean mCheckedForSetup;
953
954    /**
955     * The time at which we will allow normal application switches again,
956     * after a call to {@link #stopAppSwitches()}.
957     */
958    long mAppSwitchesAllowedTime;
959
960    /**
961     * This is set to true after the first switch after mAppSwitchesAllowedTime
962     * is set; any switches after that will clear the time.
963     */
964    boolean mDidAppSwitch;
965
966    /**
967     * Last time (in realtime) at which we checked for power usage.
968     */
969    long mLastPowerCheckRealtime;
970
971    /**
972     * Last time (in uptime) at which we checked for power usage.
973     */
974    long mLastPowerCheckUptime;
975
976    /**
977     * Set while we are wanting to sleep, to prevent any
978     * activities from being started/resumed.
979     */
980    private boolean mSleeping = false;
981
982    /**
983     * Set while we are running a voice interaction.  This overrides
984     * sleeping while it is active.
985     */
986    private boolean mRunningVoice = false;
987
988    /**
989     * State of external calls telling us if the device is awake or asleep.
990     */
991    private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
992
993    static final int LOCK_SCREEN_HIDDEN = 0;
994    static final int LOCK_SCREEN_LEAVING = 1;
995    static final int LOCK_SCREEN_SHOWN = 2;
996    /**
997     * State of external call telling us if the lock screen is shown.
998     */
999    int mLockScreenShown = LOCK_SCREEN_HIDDEN;
1000
1001    /**
1002     * Set if we are shutting down the system, similar to sleeping.
1003     */
1004    boolean mShuttingDown = false;
1005
1006    /**
1007     * Current sequence id for oom_adj computation traversal.
1008     */
1009    int mAdjSeq = 0;
1010
1011    /**
1012     * Current sequence id for process LRU updating.
1013     */
1014    int mLruSeq = 0;
1015
1016    /**
1017     * Keep track of the non-cached/empty process we last found, to help
1018     * determine how to distribute cached/empty processes next time.
1019     */
1020    int mNumNonCachedProcs = 0;
1021
1022    /**
1023     * Keep track of the number of cached hidden procs, to balance oom adj
1024     * distribution between those and empty procs.
1025     */
1026    int mNumCachedHiddenProcs = 0;
1027
1028    /**
1029     * Keep track of the number of service processes we last found, to
1030     * determine on the next iteration which should be B services.
1031     */
1032    int mNumServiceProcs = 0;
1033    int mNewNumAServiceProcs = 0;
1034    int mNewNumServiceProcs = 0;
1035
1036    /**
1037     * Allow the current computed overall memory level of the system to go down?
1038     * This is set to false when we are killing processes for reasons other than
1039     * memory management, so that the now smaller process list will not be taken as
1040     * an indication that memory is tighter.
1041     */
1042    boolean mAllowLowerMemLevel = false;
1043
1044    /**
1045     * The last computed memory level, for holding when we are in a state that
1046     * processes are going away for other reasons.
1047     */
1048    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1049
1050    /**
1051     * The last total number of process we have, to determine if changes actually look
1052     * like a shrinking number of process due to lower RAM.
1053     */
1054    int mLastNumProcesses;
1055
1056    /**
1057     * The uptime of the last time we performed idle maintenance.
1058     */
1059    long mLastIdleTime = SystemClock.uptimeMillis();
1060
1061    /**
1062     * Total time spent with RAM that has been added in the past since the last idle time.
1063     */
1064    long mLowRamTimeSinceLastIdle = 0;
1065
1066    /**
1067     * If RAM is currently low, when that horrible situation started.
1068     */
1069    long mLowRamStartTime = 0;
1070
1071    /**
1072     * For reporting to battery stats the current top application.
1073     */
1074    private String mCurResumedPackage = null;
1075    private int mCurResumedUid = -1;
1076
1077    /**
1078     * For reporting to battery stats the apps currently running foreground
1079     * service.  The ProcessMap is package/uid tuples; each of these contain
1080     * an array of the currently foreground processes.
1081     */
1082    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1083            = new ProcessMap<ArrayList<ProcessRecord>>();
1084
1085    /**
1086     * This is set if we had to do a delayed dexopt of an app before launching
1087     * it, to increase the ANR timeouts in that case.
1088     */
1089    boolean mDidDexOpt;
1090
1091    /**
1092     * Set if the systemServer made a call to enterSafeMode.
1093     */
1094    boolean mSafeMode;
1095
1096    /**
1097     * If true, we are running under a test environment so will sample PSS from processes
1098     * much more rapidly to try to collect better data when the tests are rapidly
1099     * running through apps.
1100     */
1101    boolean mTestPssMode = false;
1102
1103    String mDebugApp = null;
1104    boolean mWaitForDebugger = false;
1105    boolean mDebugTransient = false;
1106    String mOrigDebugApp = null;
1107    boolean mOrigWaitForDebugger = false;
1108    boolean mAlwaysFinishActivities = false;
1109    IActivityController mController = null;
1110    String mProfileApp = null;
1111    ProcessRecord mProfileProc = null;
1112    String mProfileFile;
1113    ParcelFileDescriptor mProfileFd;
1114    int mSamplingInterval = 0;
1115    boolean mAutoStopProfiler = false;
1116    int mProfileType = 0;
1117    String mOpenGlTraceApp = null;
1118
1119    final long[] mTmpLong = new long[1];
1120
1121    static class ProcessChangeItem {
1122        static final int CHANGE_ACTIVITIES = 1<<0;
1123        static final int CHANGE_PROCESS_STATE = 1<<1;
1124        int changes;
1125        int uid;
1126        int pid;
1127        int processState;
1128        boolean foregroundActivities;
1129    }
1130
1131    final RemoteCallbackList<IProcessObserver> mProcessObservers
1132            = new RemoteCallbackList<IProcessObserver>();
1133    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1134
1135    final ArrayList<ProcessChangeItem> mPendingProcessChanges
1136            = new ArrayList<ProcessChangeItem>();
1137    final ArrayList<ProcessChangeItem> mAvailProcessChanges
1138            = new ArrayList<ProcessChangeItem>();
1139
1140    /**
1141     * Runtime CPU use collection thread.  This object's lock is used to
1142     * perform synchronization with the thread (notifying it to run).
1143     */
1144    final Thread mProcessCpuThread;
1145
1146    /**
1147     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1148     * Must acquire this object's lock when accessing it.
1149     * NOTE: this lock will be held while doing long operations (trawling
1150     * through all processes in /proc), so it should never be acquired by
1151     * any critical paths such as when holding the main activity manager lock.
1152     */
1153    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1154            MONITOR_THREAD_CPU_USAGE);
1155    final AtomicLong mLastCpuTime = new AtomicLong(0);
1156    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1157
1158    long mLastWriteTime = 0;
1159
1160    /**
1161     * Used to retain an update lock when the foreground activity is in
1162     * immersive mode.
1163     */
1164    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1165
1166    /**
1167     * Set to true after the system has finished booting.
1168     */
1169    boolean mBooted = false;
1170
1171    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1172    int mProcessLimitOverride = -1;
1173
1174    WindowManagerService mWindowManager;
1175
1176    final ActivityThread mSystemThread;
1177
1178    // Holds the current foreground user's id
1179    int mCurrentUserId = 0;
1180    // Holds the target user's id during a user switch
1181    int mTargetUserId = UserHandle.USER_NULL;
1182    // If there are multiple profiles for the current user, their ids are here
1183    // Currently only the primary user can have managed profiles
1184    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1185
1186    /**
1187     * Mapping from each known user ID to the profile group ID it is associated with.
1188     */
1189    SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray();
1190
1191    private UserManagerService mUserManager;
1192
1193    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1194        final ProcessRecord mApp;
1195        final int mPid;
1196        final IApplicationThread mAppThread;
1197
1198        AppDeathRecipient(ProcessRecord app, int pid,
1199                IApplicationThread thread) {
1200            if (localLOGV) Slog.v(
1201                TAG, "New death recipient " + this
1202                + " for thread " + thread.asBinder());
1203            mApp = app;
1204            mPid = pid;
1205            mAppThread = thread;
1206        }
1207
1208        @Override
1209        public void binderDied() {
1210            if (localLOGV) Slog.v(
1211                TAG, "Death received in " + this
1212                + " for thread " + mAppThread.asBinder());
1213            synchronized(ActivityManagerService.this) {
1214                appDiedLocked(mApp, mPid, mAppThread);
1215            }
1216        }
1217    }
1218
1219    static final int SHOW_ERROR_MSG = 1;
1220    static final int SHOW_NOT_RESPONDING_MSG = 2;
1221    static final int SHOW_FACTORY_ERROR_MSG = 3;
1222    static final int UPDATE_CONFIGURATION_MSG = 4;
1223    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1224    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1225    static final int SERVICE_TIMEOUT_MSG = 12;
1226    static final int UPDATE_TIME_ZONE = 13;
1227    static final int SHOW_UID_ERROR_MSG = 14;
1228    static final int SHOW_FINGERPRINT_ERROR_MSG = 15;
1229    static final int PROC_START_TIMEOUT_MSG = 20;
1230    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1231    static final int KILL_APPLICATION_MSG = 22;
1232    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1233    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1234    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1235    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1236    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1237    static final int CLEAR_DNS_CACHE_MSG = 28;
1238    static final int UPDATE_HTTP_PROXY_MSG = 29;
1239    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1240    static final int DISPATCH_PROCESSES_CHANGED = 31;
1241    static final int DISPATCH_PROCESS_DIED = 32;
1242    static final int REPORT_MEM_USAGE_MSG = 33;
1243    static final int REPORT_USER_SWITCH_MSG = 34;
1244    static final int CONTINUE_USER_SWITCH_MSG = 35;
1245    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1246    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1247    static final int PERSIST_URI_GRANTS_MSG = 38;
1248    static final int REQUEST_ALL_PSS_MSG = 39;
1249    static final int START_PROFILES_MSG = 40;
1250    static final int UPDATE_TIME = 41;
1251    static final int SYSTEM_USER_START_MSG = 42;
1252    static final int SYSTEM_USER_CURRENT_MSG = 43;
1253    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1254    static final int FINISH_BOOTING_MSG = 45;
1255    static final int START_USER_SWITCH_MSG = 46;
1256    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1257    static final int DISMISS_DIALOG_MSG = 48;
1258    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49;
1259    static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 50;
1260
1261    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1262    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1263    static final int FIRST_COMPAT_MODE_MSG = 300;
1264    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1265
1266    CompatModeDialog mCompatModeDialog;
1267    long mLastMemUsageReportTime = 0;
1268
1269    /**
1270     * Flag whether the current user is a "monkey", i.e. whether
1271     * the UI is driven by a UI automation tool.
1272     */
1273    private boolean mUserIsMonkey;
1274
1275    /** Flag whether the device has a Recents UI */
1276    boolean mHasRecents;
1277
1278    /** The dimensions of the thumbnails in the Recents UI. */
1279    int mThumbnailWidth;
1280    int mThumbnailHeight;
1281
1282    final ServiceThread mHandlerThread;
1283    final MainHandler mHandler;
1284
1285    final class MainHandler extends Handler {
1286        public MainHandler(Looper looper) {
1287            super(looper, null, true);
1288        }
1289
1290        @Override
1291        public void handleMessage(Message msg) {
1292            switch (msg.what) {
1293            case SHOW_ERROR_MSG: {
1294                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1295                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1296                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1297                synchronized (ActivityManagerService.this) {
1298                    ProcessRecord proc = (ProcessRecord)data.get("app");
1299                    AppErrorResult res = (AppErrorResult) data.get("result");
1300                    if (proc != null && proc.crashDialog != null) {
1301                        Slog.e(TAG, "App already has crash dialog: " + proc);
1302                        if (res != null) {
1303                            res.set(0);
1304                        }
1305                        return;
1306                    }
1307                    boolean isBackground = (UserHandle.getAppId(proc.uid)
1308                            >= Process.FIRST_APPLICATION_UID
1309                            && proc.pid != MY_PID);
1310                    for (int userId : mCurrentProfileIds) {
1311                        isBackground &= (proc.userId != userId);
1312                    }
1313                    if (isBackground && !showBackground) {
1314                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1315                        if (res != null) {
1316                            res.set(0);
1317                        }
1318                        return;
1319                    }
1320                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1321                        Dialog d = new AppErrorDialog(mContext,
1322                                ActivityManagerService.this, res, proc);
1323                        d.show();
1324                        proc.crashDialog = d;
1325                    } else {
1326                        // The device is asleep, so just pretend that the user
1327                        // saw a crash dialog and hit "force quit".
1328                        if (res != null) {
1329                            res.set(0);
1330                        }
1331                    }
1332                }
1333
1334                ensureBootCompleted();
1335            } break;
1336            case SHOW_NOT_RESPONDING_MSG: {
1337                synchronized (ActivityManagerService.this) {
1338                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1339                    ProcessRecord proc = (ProcessRecord)data.get("app");
1340                    if (proc != null && proc.anrDialog != null) {
1341                        Slog.e(TAG, "App already has anr dialog: " + proc);
1342                        return;
1343                    }
1344
1345                    Intent intent = new Intent("android.intent.action.ANR");
1346                    if (!mProcessesReady) {
1347                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1348                                | Intent.FLAG_RECEIVER_FOREGROUND);
1349                    }
1350                    broadcastIntentLocked(null, null, intent,
1351                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1352                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1353
1354                    if (mShowDialogs) {
1355                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1356                                mContext, proc, (ActivityRecord)data.get("activity"),
1357                                msg.arg1 != 0);
1358                        d.show();
1359                        proc.anrDialog = d;
1360                    } else {
1361                        // Just kill the app if there is no dialog to be shown.
1362                        killAppAtUsersRequest(proc, null);
1363                    }
1364                }
1365
1366                ensureBootCompleted();
1367            } break;
1368            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1369                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1370                synchronized (ActivityManagerService.this) {
1371                    ProcessRecord proc = (ProcessRecord) data.get("app");
1372                    if (proc == null) {
1373                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1374                        break;
1375                    }
1376                    if (proc.crashDialog != null) {
1377                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1378                        return;
1379                    }
1380                    AppErrorResult res = (AppErrorResult) data.get("result");
1381                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1382                        Dialog d = new StrictModeViolationDialog(mContext,
1383                                ActivityManagerService.this, res, proc);
1384                        d.show();
1385                        proc.crashDialog = d;
1386                    } else {
1387                        // The device is asleep, so just pretend that the user
1388                        // saw a crash dialog and hit "force quit".
1389                        res.set(0);
1390                    }
1391                }
1392                ensureBootCompleted();
1393            } break;
1394            case SHOW_FACTORY_ERROR_MSG: {
1395                Dialog d = new FactoryErrorDialog(
1396                    mContext, msg.getData().getCharSequence("msg"));
1397                d.show();
1398                ensureBootCompleted();
1399            } break;
1400            case UPDATE_CONFIGURATION_MSG: {
1401                final ContentResolver resolver = mContext.getContentResolver();
1402                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1403            } break;
1404            case GC_BACKGROUND_PROCESSES_MSG: {
1405                synchronized (ActivityManagerService.this) {
1406                    performAppGcsIfAppropriateLocked();
1407                }
1408            } break;
1409            case WAIT_FOR_DEBUGGER_MSG: {
1410                synchronized (ActivityManagerService.this) {
1411                    ProcessRecord app = (ProcessRecord)msg.obj;
1412                    if (msg.arg1 != 0) {
1413                        if (!app.waitedForDebugger) {
1414                            Dialog d = new AppWaitingForDebuggerDialog(
1415                                    ActivityManagerService.this,
1416                                    mContext, app);
1417                            app.waitDialog = d;
1418                            app.waitedForDebugger = true;
1419                            d.show();
1420                        }
1421                    } else {
1422                        if (app.waitDialog != null) {
1423                            app.waitDialog.dismiss();
1424                            app.waitDialog = null;
1425                        }
1426                    }
1427                }
1428            } break;
1429            case SERVICE_TIMEOUT_MSG: {
1430                if (mDidDexOpt) {
1431                    mDidDexOpt = false;
1432                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1433                    nmsg.obj = msg.obj;
1434                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1435                    return;
1436                }
1437                mServices.serviceTimeout((ProcessRecord)msg.obj);
1438            } break;
1439            case UPDATE_TIME_ZONE: {
1440                synchronized (ActivityManagerService.this) {
1441                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1442                        ProcessRecord r = mLruProcesses.get(i);
1443                        if (r.thread != null) {
1444                            try {
1445                                r.thread.updateTimeZone();
1446                            } catch (RemoteException ex) {
1447                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1448                            }
1449                        }
1450                    }
1451                }
1452            } break;
1453            case CLEAR_DNS_CACHE_MSG: {
1454                synchronized (ActivityManagerService.this) {
1455                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1456                        ProcessRecord r = mLruProcesses.get(i);
1457                        if (r.thread != null) {
1458                            try {
1459                                r.thread.clearDnsCache();
1460                            } catch (RemoteException ex) {
1461                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1462                            }
1463                        }
1464                    }
1465                }
1466            } break;
1467            case UPDATE_HTTP_PROXY_MSG: {
1468                ProxyInfo proxy = (ProxyInfo)msg.obj;
1469                String host = "";
1470                String port = "";
1471                String exclList = "";
1472                Uri pacFileUrl = Uri.EMPTY;
1473                if (proxy != null) {
1474                    host = proxy.getHost();
1475                    port = Integer.toString(proxy.getPort());
1476                    exclList = proxy.getExclusionListAsString();
1477                    pacFileUrl = proxy.getPacFileUrl();
1478                }
1479                synchronized (ActivityManagerService.this) {
1480                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1481                        ProcessRecord r = mLruProcesses.get(i);
1482                        if (r.thread != null) {
1483                            try {
1484                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1485                            } catch (RemoteException ex) {
1486                                Slog.w(TAG, "Failed to update http proxy for: " +
1487                                        r.info.processName);
1488                            }
1489                        }
1490                    }
1491                }
1492            } break;
1493            case SHOW_UID_ERROR_MSG: {
1494                if (mShowDialogs) {
1495                    AlertDialog d = new BaseErrorDialog(mContext);
1496                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1497                    d.setCancelable(false);
1498                    d.setTitle(mContext.getText(R.string.android_system_label));
1499                    d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1500                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1501                            mHandler.obtainMessage(DISMISS_DIALOG_MSG, d));
1502                    d.show();
1503                }
1504            } break;
1505            case SHOW_FINGERPRINT_ERROR_MSG: {
1506                if (mShowDialogs) {
1507                    AlertDialog d = new BaseErrorDialog(mContext);
1508                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1509                    d.setCancelable(false);
1510                    d.setTitle(mContext.getText(R.string.android_system_label));
1511                    d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1512                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1513                            mHandler.obtainMessage(DISMISS_DIALOG_MSG, d));
1514                    d.show();
1515                }
1516            } break;
1517            case PROC_START_TIMEOUT_MSG: {
1518                if (mDidDexOpt) {
1519                    mDidDexOpt = false;
1520                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1521                    nmsg.obj = msg.obj;
1522                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1523                    return;
1524                }
1525                ProcessRecord app = (ProcessRecord)msg.obj;
1526                synchronized (ActivityManagerService.this) {
1527                    processStartTimedOutLocked(app);
1528                }
1529            } break;
1530            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1531                synchronized (ActivityManagerService.this) {
1532                    mStackSupervisor.doPendingActivityLaunchesLocked(true);
1533                }
1534            } break;
1535            case KILL_APPLICATION_MSG: {
1536                synchronized (ActivityManagerService.this) {
1537                    int appid = msg.arg1;
1538                    boolean restart = (msg.arg2 == 1);
1539                    Bundle bundle = (Bundle)msg.obj;
1540                    String pkg = bundle.getString("pkg");
1541                    String reason = bundle.getString("reason");
1542                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1543                            false, UserHandle.USER_ALL, reason);
1544                }
1545            } break;
1546            case FINALIZE_PENDING_INTENT_MSG: {
1547                ((PendingIntentRecord)msg.obj).completeFinalize();
1548            } break;
1549            case POST_HEAVY_NOTIFICATION_MSG: {
1550                INotificationManager inm = NotificationManager.getService();
1551                if (inm == null) {
1552                    return;
1553                }
1554
1555                ActivityRecord root = (ActivityRecord)msg.obj;
1556                ProcessRecord process = root.app;
1557                if (process == null) {
1558                    return;
1559                }
1560
1561                try {
1562                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1563                    String text = mContext.getString(R.string.heavy_weight_notification,
1564                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1565                    Notification notification = new Notification();
1566                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1567                    notification.when = 0;
1568                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1569                    notification.tickerText = text;
1570                    notification.defaults = 0; // please be quiet
1571                    notification.sound = null;
1572                    notification.vibrate = null;
1573                    notification.color = mContext.getResources().getColor(
1574                            com.android.internal.R.color.system_notification_accent_color);
1575                    notification.setLatestEventInfo(context, text,
1576                            mContext.getText(R.string.heavy_weight_notification_detail),
1577                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1578                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1579                                    new UserHandle(root.userId)));
1580
1581                    try {
1582                        int[] outId = new int[1];
1583                        inm.enqueueNotificationWithTag("android", "android", null,
1584                                R.string.heavy_weight_notification,
1585                                notification, outId, root.userId);
1586                    } catch (RuntimeException e) {
1587                        Slog.w(ActivityManagerService.TAG,
1588                                "Error showing notification for heavy-weight app", e);
1589                    } catch (RemoteException e) {
1590                    }
1591                } catch (NameNotFoundException e) {
1592                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1593                }
1594            } break;
1595            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1596                INotificationManager inm = NotificationManager.getService();
1597                if (inm == null) {
1598                    return;
1599                }
1600                try {
1601                    inm.cancelNotificationWithTag("android", null,
1602                            R.string.heavy_weight_notification,  msg.arg1);
1603                } catch (RuntimeException e) {
1604                    Slog.w(ActivityManagerService.TAG,
1605                            "Error canceling notification for service", e);
1606                } catch (RemoteException e) {
1607                }
1608            } break;
1609            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1610                synchronized (ActivityManagerService.this) {
1611                    checkExcessivePowerUsageLocked(true);
1612                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1613                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1614                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1615                }
1616            } break;
1617            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1618                synchronized (ActivityManagerService.this) {
1619                    ActivityRecord ar = (ActivityRecord)msg.obj;
1620                    if (mCompatModeDialog != null) {
1621                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1622                                ar.info.applicationInfo.packageName)) {
1623                            return;
1624                        }
1625                        mCompatModeDialog.dismiss();
1626                        mCompatModeDialog = null;
1627                    }
1628                    if (ar != null && false) {
1629                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1630                                ar.packageName)) {
1631                            int mode = mCompatModePackages.computeCompatModeLocked(
1632                                    ar.info.applicationInfo);
1633                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1634                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1635                                mCompatModeDialog = new CompatModeDialog(
1636                                        ActivityManagerService.this, mContext,
1637                                        ar.info.applicationInfo);
1638                                mCompatModeDialog.show();
1639                            }
1640                        }
1641                    }
1642                }
1643                break;
1644            }
1645            case DISPATCH_PROCESSES_CHANGED: {
1646                dispatchProcessesChanged();
1647                break;
1648            }
1649            case DISPATCH_PROCESS_DIED: {
1650                final int pid = msg.arg1;
1651                final int uid = msg.arg2;
1652                dispatchProcessDied(pid, uid);
1653                break;
1654            }
1655            case REPORT_MEM_USAGE_MSG: {
1656                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1657                Thread thread = new Thread() {
1658                    @Override public void run() {
1659                        reportMemUsage(memInfos);
1660                    }
1661                };
1662                thread.start();
1663                break;
1664            }
1665            case START_USER_SWITCH_MSG: {
1666                showUserSwitchDialog(msg.arg1, (String) msg.obj);
1667                break;
1668            }
1669            case REPORT_USER_SWITCH_MSG: {
1670                dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1671                break;
1672            }
1673            case CONTINUE_USER_SWITCH_MSG: {
1674                continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1675                break;
1676            }
1677            case USER_SWITCH_TIMEOUT_MSG: {
1678                timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1679                break;
1680            }
1681            case IMMERSIVE_MODE_LOCK_MSG: {
1682                final boolean nextState = (msg.arg1 != 0);
1683                if (mUpdateLock.isHeld() != nextState) {
1684                    if (DEBUG_IMMERSIVE) {
1685                        final ActivityRecord r = (ActivityRecord) msg.obj;
1686                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1687                    }
1688                    if (nextState) {
1689                        mUpdateLock.acquire();
1690                    } else {
1691                        mUpdateLock.release();
1692                    }
1693                }
1694                break;
1695            }
1696            case PERSIST_URI_GRANTS_MSG: {
1697                writeGrantedUriPermissions();
1698                break;
1699            }
1700            case REQUEST_ALL_PSS_MSG: {
1701                synchronized (ActivityManagerService.this) {
1702                    requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1703                }
1704                break;
1705            }
1706            case START_PROFILES_MSG: {
1707                synchronized (ActivityManagerService.this) {
1708                    startProfilesLocked();
1709                }
1710                break;
1711            }
1712            case UPDATE_TIME: {
1713                synchronized (ActivityManagerService.this) {
1714                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1715                        ProcessRecord r = mLruProcesses.get(i);
1716                        if (r.thread != null) {
1717                            try {
1718                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1719                            } catch (RemoteException ex) {
1720                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1721                            }
1722                        }
1723                    }
1724                }
1725                break;
1726            }
1727            case SYSTEM_USER_START_MSG: {
1728                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1729                        Integer.toString(msg.arg1), msg.arg1);
1730                mSystemServiceManager.startUser(msg.arg1);
1731                break;
1732            }
1733            case SYSTEM_USER_CURRENT_MSG: {
1734                mBatteryStatsService.noteEvent(
1735                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1736                        Integer.toString(msg.arg2), msg.arg2);
1737                mBatteryStatsService.noteEvent(
1738                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1739                        Integer.toString(msg.arg1), msg.arg1);
1740                mSystemServiceManager.switchUser(msg.arg1);
1741                break;
1742            }
1743            case ENTER_ANIMATION_COMPLETE_MSG: {
1744                synchronized (ActivityManagerService.this) {
1745                    ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj);
1746                    if (r != null && r.app != null && r.app.thread != null) {
1747                        try {
1748                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1749                        } catch (RemoteException e) {
1750                        }
1751                    }
1752                }
1753                break;
1754            }
1755            case FINISH_BOOTING_MSG: {
1756                if (msg.arg1 != 0) {
1757                    finishBooting();
1758                }
1759                if (msg.arg2 != 0) {
1760                    enableScreenAfterBoot();
1761                }
1762                break;
1763            }
1764            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
1765                try {
1766                    Locale l = (Locale) msg.obj;
1767                    IBinder service = ServiceManager.getService("mount");
1768                    IMountService mountService = IMountService.Stub.asInterface(service);
1769                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
1770                    mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
1771                } catch (RemoteException e) {
1772                    Log.e(TAG, "Error storing locale for decryption UI", e);
1773                }
1774                break;
1775            }
1776            case DISMISS_DIALOG_MSG: {
1777                final Dialog d = (Dialog) msg.obj;
1778                d.dismiss();
1779                break;
1780            }
1781            case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: {
1782                synchronized (ActivityManagerService.this) {
1783                    int i = mTaskStackListeners.beginBroadcast();
1784                    while (i > 0) {
1785                        i--;
1786                        try {
1787                            // Make a one-way callback to the listener
1788                            mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged();
1789                        } catch (RemoteException e){
1790                            // Handled by the RemoteCallbackList
1791                        }
1792                    }
1793                    mTaskStackListeners.finishBroadcast();
1794                }
1795                break;
1796            }
1797            case NOTIFY_CLEARTEXT_NETWORK_MSG: {
1798                final int uid = msg.arg1;
1799                final byte[] firstPacket = (byte[]) msg.obj;
1800
1801                synchronized (mPidsSelfLocked) {
1802                    for (int i = 0; i < mPidsSelfLocked.size(); i++) {
1803                        final ProcessRecord p = mPidsSelfLocked.valueAt(i);
1804                        if (p.uid == uid) {
1805                            try {
1806                                p.thread.notifyCleartextNetwork(firstPacket);
1807                            } catch (RemoteException ignored) {
1808                            }
1809                        }
1810                    }
1811                }
1812                break;
1813            }
1814            }
1815        }
1816    };
1817
1818    static final int COLLECT_PSS_BG_MSG = 1;
1819
1820    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1821        @Override
1822        public void handleMessage(Message msg) {
1823            switch (msg.what) {
1824            case COLLECT_PSS_BG_MSG: {
1825                long start = SystemClock.uptimeMillis();
1826                MemInfoReader memInfo = null;
1827                synchronized (ActivityManagerService.this) {
1828                    if (mFullPssPending) {
1829                        mFullPssPending = false;
1830                        memInfo = new MemInfoReader();
1831                    }
1832                }
1833                if (memInfo != null) {
1834                    updateCpuStatsNow();
1835                    long nativeTotalPss = 0;
1836                    synchronized (mProcessCpuTracker) {
1837                        final int N = mProcessCpuTracker.countStats();
1838                        for (int j=0; j<N; j++) {
1839                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
1840                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
1841                                // This is definitely an application process; skip it.
1842                                continue;
1843                            }
1844                            synchronized (mPidsSelfLocked) {
1845                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
1846                                    // This is one of our own processes; skip it.
1847                                    continue;
1848                                }
1849                            }
1850                            nativeTotalPss += Debug.getPss(st.pid, null, null);
1851                        }
1852                    }
1853                    memInfo.readMemInfo();
1854                    synchronized (ActivityManagerService.this) {
1855                        if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in "
1856                                + (SystemClock.uptimeMillis()-start) + "ms");
1857                        mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
1858                                memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
1859                                memInfo.getKernelUsedSizeKb(), nativeTotalPss);
1860                    }
1861                }
1862
1863                int num = 0;
1864                long[] tmp = new long[1];
1865                do {
1866                    ProcessRecord proc;
1867                    int procState;
1868                    int pid;
1869                    long lastPssTime;
1870                    synchronized (ActivityManagerService.this) {
1871                        if (mPendingPssProcesses.size() <= 0) {
1872                            if (mTestPssMode || DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num
1873                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1874                            mPendingPssProcesses.clear();
1875                            return;
1876                        }
1877                        proc = mPendingPssProcesses.remove(0);
1878                        procState = proc.pssProcState;
1879                        lastPssTime = proc.lastPssTime;
1880                        if (proc.thread != null && procState == proc.setProcState
1881                                && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
1882                                        < SystemClock.uptimeMillis()) {
1883                            pid = proc.pid;
1884                        } else {
1885                            proc = null;
1886                            pid = 0;
1887                        }
1888                    }
1889                    if (proc != null) {
1890                        long pss = Debug.getPss(pid, tmp, null);
1891                        synchronized (ActivityManagerService.this) {
1892                            if (pss != 0 && proc.thread != null && proc.setProcState == procState
1893                                    && proc.pid == pid && proc.lastPssTime == lastPssTime) {
1894                                num++;
1895                                recordPssSample(proc, procState, pss, tmp[0],
1896                                        SystemClock.uptimeMillis());
1897                            }
1898                        }
1899                    }
1900                } while (true);
1901            }
1902            }
1903        }
1904    };
1905
1906    public void setSystemProcess() {
1907        try {
1908            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
1909            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
1910            ServiceManager.addService("meminfo", new MemBinder(this));
1911            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
1912            ServiceManager.addService("dbinfo", new DbBinder(this));
1913            if (MONITOR_CPU_USAGE) {
1914                ServiceManager.addService("cpuinfo", new CpuBinder(this));
1915            }
1916            ServiceManager.addService("permission", new PermissionController(this));
1917
1918            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
1919                    "android", STOCK_PM_FLAGS);
1920            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
1921
1922            synchronized (this) {
1923                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
1924                app.persistent = true;
1925                app.pid = MY_PID;
1926                app.maxAdj = ProcessList.SYSTEM_ADJ;
1927                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
1928                mProcessNames.put(app.processName, app.uid, app);
1929                synchronized (mPidsSelfLocked) {
1930                    mPidsSelfLocked.put(app.pid, app);
1931                }
1932                updateLruProcessLocked(app, false, null);
1933                updateOomAdjLocked();
1934            }
1935        } catch (PackageManager.NameNotFoundException e) {
1936            throw new RuntimeException(
1937                    "Unable to find android system package", e);
1938        }
1939    }
1940
1941    public void setWindowManager(WindowManagerService wm) {
1942        mWindowManager = wm;
1943        mStackSupervisor.setWindowManager(wm);
1944    }
1945
1946    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
1947        mUsageStatsService = usageStatsManager;
1948    }
1949
1950    public void startObservingNativeCrashes() {
1951        final NativeCrashListener ncl = new NativeCrashListener(this);
1952        ncl.start();
1953    }
1954
1955    public IAppOpsService getAppOpsService() {
1956        return mAppOpsService;
1957    }
1958
1959    static class MemBinder extends Binder {
1960        ActivityManagerService mActivityManagerService;
1961        MemBinder(ActivityManagerService activityManagerService) {
1962            mActivityManagerService = activityManagerService;
1963        }
1964
1965        @Override
1966        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1967            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1968                    != PackageManager.PERMISSION_GRANTED) {
1969                pw.println("Permission Denial: can't dump meminfo from from pid="
1970                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1971                        + " without permission " + android.Manifest.permission.DUMP);
1972                return;
1973            }
1974
1975            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
1976        }
1977    }
1978
1979    static class GraphicsBinder extends Binder {
1980        ActivityManagerService mActivityManagerService;
1981        GraphicsBinder(ActivityManagerService activityManagerService) {
1982            mActivityManagerService = activityManagerService;
1983        }
1984
1985        @Override
1986        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1987            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1988                    != PackageManager.PERMISSION_GRANTED) {
1989                pw.println("Permission Denial: can't dump gfxinfo from from pid="
1990                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1991                        + " without permission " + android.Manifest.permission.DUMP);
1992                return;
1993            }
1994
1995            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
1996        }
1997    }
1998
1999    static class DbBinder extends Binder {
2000        ActivityManagerService mActivityManagerService;
2001        DbBinder(ActivityManagerService activityManagerService) {
2002            mActivityManagerService = activityManagerService;
2003        }
2004
2005        @Override
2006        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2007            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2008                    != PackageManager.PERMISSION_GRANTED) {
2009                pw.println("Permission Denial: can't dump dbinfo from from pid="
2010                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2011                        + " without permission " + android.Manifest.permission.DUMP);
2012                return;
2013            }
2014
2015            mActivityManagerService.dumpDbInfo(fd, pw, args);
2016        }
2017    }
2018
2019    static class CpuBinder extends Binder {
2020        ActivityManagerService mActivityManagerService;
2021        CpuBinder(ActivityManagerService activityManagerService) {
2022            mActivityManagerService = activityManagerService;
2023        }
2024
2025        @Override
2026        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2027            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2028                    != PackageManager.PERMISSION_GRANTED) {
2029                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2030                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2031                        + " without permission " + android.Manifest.permission.DUMP);
2032                return;
2033            }
2034
2035            synchronized (mActivityManagerService.mProcessCpuTracker) {
2036                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2037                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2038                        SystemClock.uptimeMillis()));
2039            }
2040        }
2041    }
2042
2043    public static final class Lifecycle extends SystemService {
2044        private final ActivityManagerService mService;
2045
2046        public Lifecycle(Context context) {
2047            super(context);
2048            mService = new ActivityManagerService(context);
2049        }
2050
2051        @Override
2052        public void onStart() {
2053            mService.start();
2054        }
2055
2056        public ActivityManagerService getService() {
2057            return mService;
2058        }
2059    }
2060
2061    // Note: This method is invoked on the main thread but may need to attach various
2062    // handlers to other threads.  So take care to be explicit about the looper.
2063    public ActivityManagerService(Context systemContext) {
2064        mContext = systemContext;
2065        mFactoryTest = FactoryTest.getMode();
2066        mSystemThread = ActivityThread.currentActivityThread();
2067
2068        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2069
2070        mHandlerThread = new ServiceThread(TAG,
2071                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2072        mHandlerThread.start();
2073        mHandler = new MainHandler(mHandlerThread.getLooper());
2074
2075        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2076                "foreground", BROADCAST_FG_TIMEOUT, false);
2077        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2078                "background", BROADCAST_BG_TIMEOUT, true);
2079        mBroadcastQueues[0] = mFgBroadcastQueue;
2080        mBroadcastQueues[1] = mBgBroadcastQueue;
2081
2082        mServices = new ActiveServices(this);
2083        mProviderMap = new ProviderMap(this);
2084
2085        // TODO: Move creation of battery stats service outside of activity manager service.
2086        File dataDir = Environment.getDataDirectory();
2087        File systemDir = new File(dataDir, "system");
2088        systemDir.mkdirs();
2089        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2090        mBatteryStatsService.getActiveStatistics().readLocked();
2091        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2092        mOnBattery = DEBUG_POWER ? true
2093                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2094        mBatteryStatsService.getActiveStatistics().setCallback(this);
2095
2096        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2097
2098        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2099
2100        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2101
2102        // User 0 is the first and only user that runs at boot.
2103        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2104        mUserLru.add(Integer.valueOf(0));
2105        updateStartedUserArrayLocked();
2106
2107        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2108            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2109
2110        mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2111
2112        mConfiguration.setToDefaults();
2113        mConfiguration.locale = Locale.getDefault();
2114
2115        mConfigurationSeq = mConfiguration.seq = 1;
2116        mProcessCpuTracker.init();
2117
2118        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2119        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2120        mRecentTasks = new RecentTasks(this);
2121        mStackSupervisor = new ActivityStackSupervisor(this, mRecentTasks);
2122        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor, mRecentTasks);
2123
2124        mProcessCpuThread = new Thread("CpuTracker") {
2125            @Override
2126            public void run() {
2127                while (true) {
2128                    try {
2129                        try {
2130                            synchronized(this) {
2131                                final long now = SystemClock.uptimeMillis();
2132                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2133                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2134                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2135                                //        + ", write delay=" + nextWriteDelay);
2136                                if (nextWriteDelay < nextCpuDelay) {
2137                                    nextCpuDelay = nextWriteDelay;
2138                                }
2139                                if (nextCpuDelay > 0) {
2140                                    mProcessCpuMutexFree.set(true);
2141                                    this.wait(nextCpuDelay);
2142                                }
2143                            }
2144                        } catch (InterruptedException e) {
2145                        }
2146                        updateCpuStatsNow();
2147                    } catch (Exception e) {
2148                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2149                    }
2150                }
2151            }
2152        };
2153
2154        Watchdog.getInstance().addMonitor(this);
2155        Watchdog.getInstance().addThread(mHandler);
2156    }
2157
2158    public void setSystemServiceManager(SystemServiceManager mgr) {
2159        mSystemServiceManager = mgr;
2160    }
2161
2162    public void setInstaller(Installer installer) {
2163        mInstaller = installer;
2164    }
2165
2166    private void start() {
2167        Process.removeAllProcessGroups();
2168        mProcessCpuThread.start();
2169
2170        mBatteryStatsService.publish(mContext);
2171        mAppOpsService.publish(mContext);
2172        Slog.d("AppOps", "AppOpsService published");
2173        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2174    }
2175
2176    public void initPowerManagement() {
2177        mStackSupervisor.initPowerManagement();
2178        mBatteryStatsService.initPowerManagement();
2179    }
2180
2181    @Override
2182    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2183            throws RemoteException {
2184        if (code == SYSPROPS_TRANSACTION) {
2185            // We need to tell all apps about the system property change.
2186            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2187            synchronized(this) {
2188                final int NP = mProcessNames.getMap().size();
2189                for (int ip=0; ip<NP; ip++) {
2190                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2191                    final int NA = apps.size();
2192                    for (int ia=0; ia<NA; ia++) {
2193                        ProcessRecord app = apps.valueAt(ia);
2194                        if (app.thread != null) {
2195                            procs.add(app.thread.asBinder());
2196                        }
2197                    }
2198                }
2199            }
2200
2201            int N = procs.size();
2202            for (int i=0; i<N; i++) {
2203                Parcel data2 = Parcel.obtain();
2204                try {
2205                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2206                } catch (RemoteException e) {
2207                }
2208                data2.recycle();
2209            }
2210        }
2211        try {
2212            return super.onTransact(code, data, reply, flags);
2213        } catch (RuntimeException e) {
2214            // The activity manager only throws security exceptions, so let's
2215            // log all others.
2216            if (!(e instanceof SecurityException)) {
2217                Slog.wtf(TAG, "Activity Manager Crash", e);
2218            }
2219            throw e;
2220        }
2221    }
2222
2223    void updateCpuStats() {
2224        final long now = SystemClock.uptimeMillis();
2225        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2226            return;
2227        }
2228        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2229            synchronized (mProcessCpuThread) {
2230                mProcessCpuThread.notify();
2231            }
2232        }
2233    }
2234
2235    void updateCpuStatsNow() {
2236        synchronized (mProcessCpuTracker) {
2237            mProcessCpuMutexFree.set(false);
2238            final long now = SystemClock.uptimeMillis();
2239            boolean haveNewCpuStats = false;
2240
2241            if (MONITOR_CPU_USAGE &&
2242                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2243                mLastCpuTime.set(now);
2244                haveNewCpuStats = true;
2245                mProcessCpuTracker.update();
2246                //Slog.i(TAG, mProcessCpu.printCurrentState());
2247                //Slog.i(TAG, "Total CPU usage: "
2248                //        + mProcessCpu.getTotalCpuPercent() + "%");
2249
2250                // Slog the cpu usage if the property is set.
2251                if ("true".equals(SystemProperties.get("events.cpu"))) {
2252                    int user = mProcessCpuTracker.getLastUserTime();
2253                    int system = mProcessCpuTracker.getLastSystemTime();
2254                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2255                    int irq = mProcessCpuTracker.getLastIrqTime();
2256                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2257                    int idle = mProcessCpuTracker.getLastIdleTime();
2258
2259                    int total = user + system + iowait + irq + softIrq + idle;
2260                    if (total == 0) total = 1;
2261
2262                    EventLog.writeEvent(EventLogTags.CPU,
2263                            ((user+system+iowait+irq+softIrq) * 100) / total,
2264                            (user * 100) / total,
2265                            (system * 100) / total,
2266                            (iowait * 100) / total,
2267                            (irq * 100) / total,
2268                            (softIrq * 100) / total);
2269                }
2270            }
2271
2272            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2273            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2274            synchronized(bstats) {
2275                synchronized(mPidsSelfLocked) {
2276                    if (haveNewCpuStats) {
2277                        if (mOnBattery) {
2278                            int perc = bstats.startAddingCpuLocked();
2279                            int totalUTime = 0;
2280                            int totalSTime = 0;
2281                            final int N = mProcessCpuTracker.countStats();
2282                            for (int i=0; i<N; i++) {
2283                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2284                                if (!st.working) {
2285                                    continue;
2286                                }
2287                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2288                                int otherUTime = (st.rel_utime*perc)/100;
2289                                int otherSTime = (st.rel_stime*perc)/100;
2290                                totalUTime += otherUTime;
2291                                totalSTime += otherSTime;
2292                                if (pr != null) {
2293                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2294                                    if (ps == null || !ps.isActive()) {
2295                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2296                                                pr.info.uid, pr.processName);
2297                                    }
2298                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2299                                            st.rel_stime-otherSTime);
2300                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2301                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2302                                } else {
2303                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2304                                    if (ps == null || !ps.isActive()) {
2305                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2306                                                bstats.mapUid(st.uid), st.name);
2307                                    }
2308                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2309                                            st.rel_stime-otherSTime);
2310                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2311                                }
2312                            }
2313                            bstats.finishAddingCpuLocked(perc, totalUTime,
2314                                    totalSTime, cpuSpeedTimes);
2315                        }
2316                    }
2317                }
2318
2319                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2320                    mLastWriteTime = now;
2321                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2322                }
2323            }
2324        }
2325    }
2326
2327    @Override
2328    public void batteryNeedsCpuUpdate() {
2329        updateCpuStatsNow();
2330    }
2331
2332    @Override
2333    public void batteryPowerChanged(boolean onBattery) {
2334        // When plugging in, update the CPU stats first before changing
2335        // the plug state.
2336        updateCpuStatsNow();
2337        synchronized (this) {
2338            synchronized(mPidsSelfLocked) {
2339                mOnBattery = DEBUG_POWER ? true : onBattery;
2340            }
2341        }
2342    }
2343
2344    /**
2345     * Initialize the application bind args. These are passed to each
2346     * process when the bindApplication() IPC is sent to the process. They're
2347     * lazily setup to make sure the services are running when they're asked for.
2348     */
2349    private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2350        if (mAppBindArgs == null) {
2351            mAppBindArgs = new HashMap<>();
2352
2353            // Isolated processes won't get this optimization, so that we don't
2354            // violate the rules about which services they have access to.
2355            if (!isolated) {
2356                // Setup the application init args
2357                mAppBindArgs.put("package", ServiceManager.getService("package"));
2358                mAppBindArgs.put("window", ServiceManager.getService("window"));
2359                mAppBindArgs.put(Context.ALARM_SERVICE,
2360                        ServiceManager.getService(Context.ALARM_SERVICE));
2361            }
2362        }
2363        return mAppBindArgs;
2364    }
2365
2366    final void setFocusedActivityLocked(ActivityRecord r) {
2367        if (mFocusedActivity != r) {
2368            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2369            mFocusedActivity = r;
2370            if (r.task != null && r.task.voiceInteractor != null) {
2371                startRunningVoiceLocked();
2372            } else {
2373                finishRunningVoiceLocked();
2374            }
2375            mStackSupervisor.setFocusedStack(r);
2376            if (r != null) {
2377                mWindowManager.setFocusedApp(r.appToken, true);
2378            }
2379            applyUpdateLockStateLocked(r);
2380        }
2381        EventLog.writeEvent(EventLogTags.AM_FOCUSED_ACTIVITY, mCurrentUserId,
2382                mFocusedActivity == null ? "NULL" : mFocusedActivity.shortComponentName);
2383    }
2384
2385    final void clearFocusedActivity(ActivityRecord r) {
2386        if (mFocusedActivity == r) {
2387            mFocusedActivity = null;
2388        }
2389    }
2390
2391    @Override
2392    public void setFocusedStack(int stackId) {
2393        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2394        synchronized (ActivityManagerService.this) {
2395            ActivityStack stack = mStackSupervisor.getStack(stackId);
2396            if (stack != null) {
2397                ActivityRecord r = stack.topRunningActivityLocked(null);
2398                if (r != null) {
2399                    setFocusedActivityLocked(r);
2400                }
2401            }
2402        }
2403    }
2404
2405    /** Sets the task stack listener that gets callbacks when a task stack changes. */
2406    @Override
2407    public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
2408        synchronized (ActivityManagerService.this) {
2409            if (listener != null) {
2410                mTaskStackListeners.register(listener);
2411            }
2412        }
2413    }
2414
2415    @Override
2416    public void notifyActivityDrawn(IBinder token) {
2417        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2418        synchronized (this) {
2419            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2420            if (r != null) {
2421                r.task.stack.notifyActivityDrawnLocked(r);
2422            }
2423        }
2424    }
2425
2426    final void applyUpdateLockStateLocked(ActivityRecord r) {
2427        // Modifications to the UpdateLock state are done on our handler, outside
2428        // the activity manager's locks.  The new state is determined based on the
2429        // state *now* of the relevant activity record.  The object is passed to
2430        // the handler solely for logging detail, not to be consulted/modified.
2431        final boolean nextState = r != null && r.immersive;
2432        mHandler.sendMessage(
2433                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2434    }
2435
2436    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2437        Message msg = Message.obtain();
2438        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2439        msg.obj = r.task.askedCompatMode ? null : r;
2440        mHandler.sendMessage(msg);
2441    }
2442
2443    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2444            String what, Object obj, ProcessRecord srcApp) {
2445        app.lastActivityTime = now;
2446
2447        if (app.activities.size() > 0) {
2448            // Don't want to touch dependent processes that are hosting activities.
2449            return index;
2450        }
2451
2452        int lrui = mLruProcesses.lastIndexOf(app);
2453        if (lrui < 0) {
2454            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2455                    + what + " " + obj + " from " + srcApp);
2456            return index;
2457        }
2458
2459        if (lrui >= index) {
2460            // Don't want to cause this to move dependent processes *back* in the
2461            // list as if they were less frequently used.
2462            return index;
2463        }
2464
2465        if (lrui >= mLruProcessActivityStart) {
2466            // Don't want to touch dependent processes that are hosting activities.
2467            return index;
2468        }
2469
2470        mLruProcesses.remove(lrui);
2471        if (index > 0) {
2472            index--;
2473        }
2474        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2475                + " in LRU list: " + app);
2476        mLruProcesses.add(index, app);
2477        return index;
2478    }
2479
2480    final void removeLruProcessLocked(ProcessRecord app) {
2481        int lrui = mLruProcesses.lastIndexOf(app);
2482        if (lrui >= 0) {
2483            if (!app.killed) {
2484                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
2485                Process.killProcessQuiet(app.pid);
2486                Process.killProcessGroup(app.info.uid, app.pid);
2487            }
2488            if (lrui <= mLruProcessActivityStart) {
2489                mLruProcessActivityStart--;
2490            }
2491            if (lrui <= mLruProcessServiceStart) {
2492                mLruProcessServiceStart--;
2493            }
2494            mLruProcesses.remove(lrui);
2495        }
2496    }
2497
2498    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2499            ProcessRecord client) {
2500        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2501                || app.treatLikeActivity;
2502        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2503        if (!activityChange && hasActivity) {
2504            // The process has activities, so we are only allowing activity-based adjustments
2505            // to move it.  It should be kept in the front of the list with other
2506            // processes that have activities, and we don't want those to change their
2507            // order except due to activity operations.
2508            return;
2509        }
2510
2511        mLruSeq++;
2512        final long now = SystemClock.uptimeMillis();
2513        app.lastActivityTime = now;
2514
2515        // First a quick reject: if the app is already at the position we will
2516        // put it, then there is nothing to do.
2517        if (hasActivity) {
2518            final int N = mLruProcesses.size();
2519            if (N > 0 && mLruProcesses.get(N-1) == app) {
2520                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2521                return;
2522            }
2523        } else {
2524            if (mLruProcessServiceStart > 0
2525                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2526                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2527                return;
2528            }
2529        }
2530
2531        int lrui = mLruProcesses.lastIndexOf(app);
2532
2533        if (app.persistent && lrui >= 0) {
2534            // We don't care about the position of persistent processes, as long as
2535            // they are in the list.
2536            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2537            return;
2538        }
2539
2540        /* In progress: compute new position first, so we can avoid doing work
2541           if the process is not actually going to move.  Not yet working.
2542        int addIndex;
2543        int nextIndex;
2544        boolean inActivity = false, inService = false;
2545        if (hasActivity) {
2546            // Process has activities, put it at the very tipsy-top.
2547            addIndex = mLruProcesses.size();
2548            nextIndex = mLruProcessServiceStart;
2549            inActivity = true;
2550        } else if (hasService) {
2551            // Process has services, put it at the top of the service list.
2552            addIndex = mLruProcessActivityStart;
2553            nextIndex = mLruProcessServiceStart;
2554            inActivity = true;
2555            inService = true;
2556        } else  {
2557            // Process not otherwise of interest, it goes to the top of the non-service area.
2558            addIndex = mLruProcessServiceStart;
2559            if (client != null) {
2560                int clientIndex = mLruProcesses.lastIndexOf(client);
2561                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2562                        + app);
2563                if (clientIndex >= 0 && addIndex > clientIndex) {
2564                    addIndex = clientIndex;
2565                }
2566            }
2567            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2568        }
2569
2570        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2571                + mLruProcessActivityStart + "): " + app);
2572        */
2573
2574        if (lrui >= 0) {
2575            if (lrui < mLruProcessActivityStart) {
2576                mLruProcessActivityStart--;
2577            }
2578            if (lrui < mLruProcessServiceStart) {
2579                mLruProcessServiceStart--;
2580            }
2581            /*
2582            if (addIndex > lrui) {
2583                addIndex--;
2584            }
2585            if (nextIndex > lrui) {
2586                nextIndex--;
2587            }
2588            */
2589            mLruProcesses.remove(lrui);
2590        }
2591
2592        /*
2593        mLruProcesses.add(addIndex, app);
2594        if (inActivity) {
2595            mLruProcessActivityStart++;
2596        }
2597        if (inService) {
2598            mLruProcessActivityStart++;
2599        }
2600        */
2601
2602        int nextIndex;
2603        if (hasActivity) {
2604            final int N = mLruProcesses.size();
2605            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2606                // Process doesn't have activities, but has clients with
2607                // activities...  move it up, but one below the top (the top
2608                // should always have a real activity).
2609                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2610                mLruProcesses.add(N-1, app);
2611                // To keep it from spamming the LRU list (by making a bunch of clients),
2612                // we will push down any other entries owned by the app.
2613                final int uid = app.info.uid;
2614                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2615                    ProcessRecord subProc = mLruProcesses.get(i);
2616                    if (subProc.info.uid == uid) {
2617                        // We want to push this one down the list.  If the process after
2618                        // it is for the same uid, however, don't do so, because we don't
2619                        // want them internally to be re-ordered.
2620                        if (mLruProcesses.get(i-1).info.uid != uid) {
2621                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2622                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2623                            ProcessRecord tmp = mLruProcesses.get(i);
2624                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2625                            mLruProcesses.set(i-1, tmp);
2626                            i--;
2627                        }
2628                    } else {
2629                        // A gap, we can stop here.
2630                        break;
2631                    }
2632                }
2633            } else {
2634                // Process has activities, put it at the very tipsy-top.
2635                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2636                mLruProcesses.add(app);
2637            }
2638            nextIndex = mLruProcessServiceStart;
2639        } else if (hasService) {
2640            // Process has services, put it at the top of the service list.
2641            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2642            mLruProcesses.add(mLruProcessActivityStart, app);
2643            nextIndex = mLruProcessServiceStart;
2644            mLruProcessActivityStart++;
2645        } else  {
2646            // Process not otherwise of interest, it goes to the top of the non-service area.
2647            int index = mLruProcessServiceStart;
2648            if (client != null) {
2649                // If there is a client, don't allow the process to be moved up higher
2650                // in the list than that client.
2651                int clientIndex = mLruProcesses.lastIndexOf(client);
2652                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2653                        + " when updating " + app);
2654                if (clientIndex <= lrui) {
2655                    // Don't allow the client index restriction to push it down farther in the
2656                    // list than it already is.
2657                    clientIndex = lrui;
2658                }
2659                if (clientIndex >= 0 && index > clientIndex) {
2660                    index = clientIndex;
2661                }
2662            }
2663            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2664            mLruProcesses.add(index, app);
2665            nextIndex = index-1;
2666            mLruProcessActivityStart++;
2667            mLruProcessServiceStart++;
2668        }
2669
2670        // If the app is currently using a content provider or service,
2671        // bump those processes as well.
2672        for (int j=app.connections.size()-1; j>=0; j--) {
2673            ConnectionRecord cr = app.connections.valueAt(j);
2674            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2675                    && cr.binding.service.app != null
2676                    && cr.binding.service.app.lruSeq != mLruSeq
2677                    && !cr.binding.service.app.persistent) {
2678                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2679                        "service connection", cr, app);
2680            }
2681        }
2682        for (int j=app.conProviders.size()-1; j>=0; j--) {
2683            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2684            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2685                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2686                        "provider reference", cpr, app);
2687            }
2688        }
2689    }
2690
2691    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2692        if (uid == Process.SYSTEM_UID) {
2693            // The system gets to run in any process.  If there are multiple
2694            // processes with the same uid, just pick the first (this
2695            // should never happen).
2696            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2697            if (procs == null) return null;
2698            final int N = procs.size();
2699            for (int i = 0; i < N; i++) {
2700                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2701            }
2702        }
2703        ProcessRecord proc = mProcessNames.get(processName, uid);
2704        if (false && proc != null && !keepIfLarge
2705                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2706                && proc.lastCachedPss >= 4000) {
2707            // Turn this condition on to cause killing to happen regularly, for testing.
2708            if (proc.baseProcessTracker != null) {
2709                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2710            }
2711            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2712        } else if (proc != null && !keepIfLarge
2713                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2714                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2715            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2716            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2717                if (proc.baseProcessTracker != null) {
2718                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2719                }
2720                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2721            }
2722        }
2723        return proc;
2724    }
2725
2726    void ensurePackageDexOpt(String packageName) {
2727        IPackageManager pm = AppGlobals.getPackageManager();
2728        try {
2729            if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) {
2730                mDidDexOpt = true;
2731            }
2732        } catch (RemoteException e) {
2733        }
2734    }
2735
2736    boolean isNextTransitionForward() {
2737        int transit = mWindowManager.getPendingAppTransition();
2738        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2739                || transit == AppTransition.TRANSIT_TASK_OPEN
2740                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2741    }
2742
2743    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
2744            String processName, String abiOverride, int uid, Runnable crashHandler) {
2745        synchronized(this) {
2746            ApplicationInfo info = new ApplicationInfo();
2747            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
2748            // For isolated processes, the former contains the parent's uid and the latter the
2749            // actual uid of the isolated process.
2750            // In the special case introduced by this method (which is, starting an isolated
2751            // process directly from the SystemServer without an actual parent app process) the
2752            // closest thing to a parent's uid is SYSTEM_UID.
2753            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
2754            // the |isolated| logic in the ProcessRecord constructor.
2755            info.uid = Process.SYSTEM_UID;
2756            info.processName = processName;
2757            info.className = entryPoint;
2758            info.packageName = "android";
2759            ProcessRecord proc = startProcessLocked(processName, info /* info */,
2760                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
2761                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
2762                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
2763                    crashHandler);
2764            return proc != null ? proc.pid : 0;
2765        }
2766    }
2767
2768    final ProcessRecord startProcessLocked(String processName,
2769            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2770            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2771            boolean isolated, boolean keepIfLarge) {
2772        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
2773                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
2774                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
2775                null /* crashHandler */);
2776    }
2777
2778    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
2779            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
2780            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
2781            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
2782        long startTime = SystemClock.elapsedRealtime();
2783        ProcessRecord app;
2784        if (!isolated) {
2785            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2786            checkTime(startTime, "startProcess: after getProcessRecord");
2787        } else {
2788            // If this is an isolated process, it can't re-use an existing process.
2789            app = null;
2790        }
2791        // We don't have to do anything more if:
2792        // (1) There is an existing application record; and
2793        // (2) The caller doesn't think it is dead, OR there is no thread
2794        //     object attached to it so we know it couldn't have crashed; and
2795        // (3) There is a pid assigned to it, so it is either starting or
2796        //     already running.
2797        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2798                + " app=" + app + " knownToBeDead=" + knownToBeDead
2799                + " thread=" + (app != null ? app.thread : null)
2800                + " pid=" + (app != null ? app.pid : -1));
2801        if (app != null && app.pid > 0) {
2802            if (!knownToBeDead || app.thread == null) {
2803                // We already have the app running, or are waiting for it to
2804                // come up (we have a pid but not yet its thread), so keep it.
2805                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2806                // If this is a new package in the process, add the package to the list
2807                app.addPackage(info.packageName, info.versionCode, mProcessStats);
2808                checkTime(startTime, "startProcess: done, added package to proc");
2809                return app;
2810            }
2811
2812            // An application record is attached to a previous process,
2813            // clean it up now.
2814            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2815            checkTime(startTime, "startProcess: bad proc running, killing");
2816            Process.killProcessGroup(app.info.uid, app.pid);
2817            handleAppDiedLocked(app, true, true);
2818            checkTime(startTime, "startProcess: done killing old proc");
2819        }
2820
2821        String hostingNameStr = hostingName != null
2822                ? hostingName.flattenToShortString() : null;
2823
2824        if (!isolated) {
2825            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2826                // If we are in the background, then check to see if this process
2827                // is bad.  If so, we will just silently fail.
2828                if (mBadProcesses.get(info.processName, info.uid) != null) {
2829                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2830                            + "/" + info.processName);
2831                    return null;
2832                }
2833            } else {
2834                // When the user is explicitly starting a process, then clear its
2835                // crash count so that we won't make it bad until they see at
2836                // least one crash dialog again, and make the process good again
2837                // if it had been bad.
2838                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2839                        + "/" + info.processName);
2840                mProcessCrashTimes.remove(info.processName, info.uid);
2841                if (mBadProcesses.get(info.processName, info.uid) != null) {
2842                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2843                            UserHandle.getUserId(info.uid), info.uid,
2844                            info.processName);
2845                    mBadProcesses.remove(info.processName, info.uid);
2846                    if (app != null) {
2847                        app.bad = false;
2848                    }
2849                }
2850            }
2851        }
2852
2853        if (app == null) {
2854            checkTime(startTime, "startProcess: creating new process record");
2855            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
2856            if (app == null) {
2857                Slog.w(TAG, "Failed making new process record for "
2858                        + processName + "/" + info.uid + " isolated=" + isolated);
2859                return null;
2860            }
2861            app.crashHandler = crashHandler;
2862            mProcessNames.put(processName, app.uid, app);
2863            if (isolated) {
2864                mIsolatedProcesses.put(app.uid, app);
2865            }
2866            checkTime(startTime, "startProcess: done creating new process record");
2867        } else {
2868            // If this is a new package in the process, add the package to the list
2869            app.addPackage(info.packageName, info.versionCode, mProcessStats);
2870            checkTime(startTime, "startProcess: added package to existing proc");
2871        }
2872
2873        // If the system is not ready yet, then hold off on starting this
2874        // process until it is.
2875        if (!mProcessesReady
2876                && !isAllowedWhileBooting(info)
2877                && !allowWhileBooting) {
2878            if (!mProcessesOnHold.contains(app)) {
2879                mProcessesOnHold.add(app);
2880            }
2881            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2882            checkTime(startTime, "startProcess: returning with proc on hold");
2883            return app;
2884        }
2885
2886        checkTime(startTime, "startProcess: stepping in to startProcess");
2887        startProcessLocked(
2888                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
2889        checkTime(startTime, "startProcess: done starting proc!");
2890        return (app.pid != 0) ? app : null;
2891    }
2892
2893    boolean isAllowedWhileBooting(ApplicationInfo ai) {
2894        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2895    }
2896
2897    private final void startProcessLocked(ProcessRecord app,
2898            String hostingType, String hostingNameStr) {
2899        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
2900                null /* entryPoint */, null /* entryPointArgs */);
2901    }
2902
2903    private final void startProcessLocked(ProcessRecord app, String hostingType,
2904            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
2905        long startTime = SystemClock.elapsedRealtime();
2906        if (app.pid > 0 && app.pid != MY_PID) {
2907            checkTime(startTime, "startProcess: removing from pids map");
2908            synchronized (mPidsSelfLocked) {
2909                mPidsSelfLocked.remove(app.pid);
2910                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2911            }
2912            checkTime(startTime, "startProcess: done removing from pids map");
2913            app.setPid(0);
2914        }
2915
2916        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2917                "startProcessLocked removing on hold: " + app);
2918        mProcessesOnHold.remove(app);
2919
2920        checkTime(startTime, "startProcess: starting to update cpu stats");
2921        updateCpuStats();
2922        checkTime(startTime, "startProcess: done updating cpu stats");
2923
2924        try {
2925            int uid = app.uid;
2926
2927            int[] gids = null;
2928            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2929            if (!app.isolated) {
2930                int[] permGids = null;
2931                try {
2932                    checkTime(startTime, "startProcess: getting gids from package manager");
2933                    final PackageManager pm = mContext.getPackageManager();
2934                    permGids = pm.getPackageGids(app.info.packageName);
2935
2936                    if (Environment.isExternalStorageEmulated()) {
2937                        checkTime(startTime, "startProcess: checking external storage perm");
2938                        if (pm.checkPermission(
2939                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2940                                app.info.packageName) == PERMISSION_GRANTED) {
2941                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2942                        } else {
2943                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2944                        }
2945                    }
2946                } catch (PackageManager.NameNotFoundException e) {
2947                    Slog.w(TAG, "Unable to retrieve gids", e);
2948                }
2949
2950                /*
2951                 * Add shared application and profile GIDs so applications can share some
2952                 * resources like shared libraries and access user-wide resources
2953                 */
2954                if (permGids == null) {
2955                    gids = new int[2];
2956                } else {
2957                    gids = new int[permGids.length + 2];
2958                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
2959                }
2960                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
2961                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
2962            }
2963            checkTime(startTime, "startProcess: building args");
2964            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
2965                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2966                        && mTopComponent != null
2967                        && app.processName.equals(mTopComponent.getPackageName())) {
2968                    uid = 0;
2969                }
2970                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
2971                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2972                    uid = 0;
2973                }
2974            }
2975            int debugFlags = 0;
2976            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2977                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2978                // Also turn on CheckJNI for debuggable apps. It's quite
2979                // awkward to turn on otherwise.
2980                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2981            }
2982            // Run the app in safe mode if its manifest requests so or the
2983            // system is booted in safe mode.
2984            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2985                mSafeMode == true) {
2986                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2987            }
2988            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2989                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2990            }
2991            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2992                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
2993            }
2994            if ("1".equals(SystemProperties.get("debug.assert"))) {
2995                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2996            }
2997
2998            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
2999            if (requiredAbi == null) {
3000                requiredAbi = Build.SUPPORTED_ABIS[0];
3001            }
3002
3003            String instructionSet = null;
3004            if (app.info.primaryCpuAbi != null) {
3005                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3006            }
3007
3008            app.gids = gids;
3009            app.requiredAbi = requiredAbi;
3010            app.instructionSet = instructionSet;
3011
3012            // Start the process.  It will either succeed and return a result containing
3013            // the PID of the new process, or else throw a RuntimeException.
3014            boolean isActivityProcess = (entryPoint == null);
3015            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3016            checkTime(startTime, "startProcess: asking zygote to start proc");
3017            Process.ProcessStartResult startResult = Process.start(entryPoint,
3018                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3019                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3020                    app.info.dataDir, entryPointArgs);
3021            checkTime(startTime, "startProcess: returned from zygote!");
3022
3023            if (app.isolated) {
3024                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3025            }
3026            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3027            checkTime(startTime, "startProcess: done updating battery stats");
3028
3029            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3030                    UserHandle.getUserId(uid), startResult.pid, uid,
3031                    app.processName, hostingType,
3032                    hostingNameStr != null ? hostingNameStr : "");
3033
3034            if (app.persistent) {
3035                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3036            }
3037
3038            checkTime(startTime, "startProcess: building log message");
3039            StringBuilder buf = mStringBuilder;
3040            buf.setLength(0);
3041            buf.append("Start proc ");
3042            buf.append(startResult.pid);
3043            buf.append(':');
3044            buf.append(app.processName);
3045            buf.append('/');
3046            UserHandle.formatUid(buf, uid);
3047            if (!isActivityProcess) {
3048                buf.append(" [");
3049                buf.append(entryPoint);
3050                buf.append("]");
3051            }
3052            buf.append(" for ");
3053            buf.append(hostingType);
3054            if (hostingNameStr != null) {
3055                buf.append(" ");
3056                buf.append(hostingNameStr);
3057            }
3058            Slog.i(TAG, buf.toString());
3059            app.setPid(startResult.pid);
3060            app.usingWrapper = startResult.usingWrapper;
3061            app.removed = false;
3062            app.killed = false;
3063            app.killedByAm = false;
3064            checkTime(startTime, "startProcess: starting to update pids map");
3065            synchronized (mPidsSelfLocked) {
3066                this.mPidsSelfLocked.put(startResult.pid, app);
3067                if (isActivityProcess) {
3068                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3069                    msg.obj = app;
3070                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3071                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3072                }
3073            }
3074            checkTime(startTime, "startProcess: done updating pids map");
3075        } catch (RuntimeException e) {
3076            // XXX do better error recovery.
3077            app.setPid(0);
3078            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3079            if (app.isolated) {
3080                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3081            }
3082            Slog.e(TAG, "Failure starting process " + app.processName, e);
3083        }
3084    }
3085
3086    void updateUsageStats(ActivityRecord component, boolean resumed) {
3087        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
3088        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3089        if (resumed) {
3090            if (mUsageStatsService != null) {
3091                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3092                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3093            }
3094            synchronized (stats) {
3095                stats.noteActivityResumedLocked(component.app.uid);
3096            }
3097        } else {
3098            if (mUsageStatsService != null) {
3099                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3100                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3101            }
3102            synchronized (stats) {
3103                stats.noteActivityPausedLocked(component.app.uid);
3104            }
3105        }
3106    }
3107
3108    Intent getHomeIntent() {
3109        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3110        intent.setComponent(mTopComponent);
3111        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3112            intent.addCategory(Intent.CATEGORY_HOME);
3113        }
3114        return intent;
3115    }
3116
3117    boolean startHomeActivityLocked(int userId) {
3118        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3119                && mTopAction == null) {
3120            // We are running in factory test mode, but unable to find
3121            // the factory test app, so just sit around displaying the
3122            // error message and don't try to start anything.
3123            return false;
3124        }
3125        Intent intent = getHomeIntent();
3126        ActivityInfo aInfo =
3127            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3128        if (aInfo != null) {
3129            intent.setComponent(new ComponentName(
3130                    aInfo.applicationInfo.packageName, aInfo.name));
3131            // Don't do this if the home app is currently being
3132            // instrumented.
3133            aInfo = new ActivityInfo(aInfo);
3134            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3135            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3136                    aInfo.applicationInfo.uid, true);
3137            if (app == null || app.instrumentationClass == null) {
3138                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3139                mStackSupervisor.startHomeActivity(intent, aInfo);
3140            }
3141        }
3142
3143        return true;
3144    }
3145
3146    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3147        ActivityInfo ai = null;
3148        ComponentName comp = intent.getComponent();
3149        try {
3150            if (comp != null) {
3151                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3152            } else {
3153                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3154                        intent,
3155                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3156                            flags, userId);
3157
3158                if (info != null) {
3159                    ai = info.activityInfo;
3160                }
3161            }
3162        } catch (RemoteException e) {
3163            // ignore
3164        }
3165
3166        return ai;
3167    }
3168
3169    /**
3170     * Starts the "new version setup screen" if appropriate.
3171     */
3172    void startSetupActivityLocked() {
3173        // Only do this once per boot.
3174        if (mCheckedForSetup) {
3175            return;
3176        }
3177
3178        // We will show this screen if the current one is a different
3179        // version than the last one shown, and we are not running in
3180        // low-level factory test mode.
3181        final ContentResolver resolver = mContext.getContentResolver();
3182        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3183                Settings.Global.getInt(resolver,
3184                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3185            mCheckedForSetup = true;
3186
3187            // See if we should be showing the platform update setup UI.
3188            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3189            List<ResolveInfo> ris = mContext.getPackageManager()
3190                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3191
3192            // We don't allow third party apps to replace this.
3193            ResolveInfo ri = null;
3194            for (int i=0; ris != null && i<ris.size(); i++) {
3195                if ((ris.get(i).activityInfo.applicationInfo.flags
3196                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3197                    ri = ris.get(i);
3198                    break;
3199                }
3200            }
3201
3202            if (ri != null) {
3203                String vers = ri.activityInfo.metaData != null
3204                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3205                        : null;
3206                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3207                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3208                            Intent.METADATA_SETUP_VERSION);
3209                }
3210                String lastVers = Settings.Secure.getString(
3211                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3212                if (vers != null && !vers.equals(lastVers)) {
3213                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3214                    intent.setComponent(new ComponentName(
3215                            ri.activityInfo.packageName, ri.activityInfo.name));
3216                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3217                            null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, null, null,
3218                            null);
3219                }
3220            }
3221        }
3222    }
3223
3224    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3225        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3226    }
3227
3228    void enforceNotIsolatedCaller(String caller) {
3229        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3230            throw new SecurityException("Isolated process not allowed to call " + caller);
3231        }
3232    }
3233
3234    void enforceShellRestriction(String restriction, int userHandle) {
3235        if (Binder.getCallingUid() == Process.SHELL_UID) {
3236            if (userHandle < 0
3237                    || mUserManager.hasUserRestriction(restriction, userHandle)) {
3238                throw new SecurityException("Shell does not have permission to access user "
3239                        + userHandle);
3240            }
3241        }
3242    }
3243
3244    @Override
3245    public int getFrontActivityScreenCompatMode() {
3246        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3247        synchronized (this) {
3248            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3249        }
3250    }
3251
3252    @Override
3253    public void setFrontActivityScreenCompatMode(int mode) {
3254        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3255                "setFrontActivityScreenCompatMode");
3256        synchronized (this) {
3257            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3258        }
3259    }
3260
3261    @Override
3262    public int getPackageScreenCompatMode(String packageName) {
3263        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3264        synchronized (this) {
3265            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3266        }
3267    }
3268
3269    @Override
3270    public void setPackageScreenCompatMode(String packageName, int mode) {
3271        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3272                "setPackageScreenCompatMode");
3273        synchronized (this) {
3274            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3275        }
3276    }
3277
3278    @Override
3279    public boolean getPackageAskScreenCompat(String packageName) {
3280        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3281        synchronized (this) {
3282            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3283        }
3284    }
3285
3286    @Override
3287    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3288        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3289                "setPackageAskScreenCompat");
3290        synchronized (this) {
3291            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3292        }
3293    }
3294
3295    private void dispatchProcessesChanged() {
3296        int N;
3297        synchronized (this) {
3298            N = mPendingProcessChanges.size();
3299            if (mActiveProcessChanges.length < N) {
3300                mActiveProcessChanges = new ProcessChangeItem[N];
3301            }
3302            mPendingProcessChanges.toArray(mActiveProcessChanges);
3303            mAvailProcessChanges.addAll(mPendingProcessChanges);
3304            mPendingProcessChanges.clear();
3305            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3306        }
3307
3308        int i = mProcessObservers.beginBroadcast();
3309        while (i > 0) {
3310            i--;
3311            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3312            if (observer != null) {
3313                try {
3314                    for (int j=0; j<N; j++) {
3315                        ProcessChangeItem item = mActiveProcessChanges[j];
3316                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3317                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3318                                    + item.pid + " uid=" + item.uid + ": "
3319                                    + item.foregroundActivities);
3320                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3321                                    item.foregroundActivities);
3322                        }
3323                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3324                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3325                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
3326                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3327                        }
3328                    }
3329                } catch (RemoteException e) {
3330                }
3331            }
3332        }
3333        mProcessObservers.finishBroadcast();
3334    }
3335
3336    private void dispatchProcessDied(int pid, int uid) {
3337        int i = mProcessObservers.beginBroadcast();
3338        while (i > 0) {
3339            i--;
3340            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3341            if (observer != null) {
3342                try {
3343                    observer.onProcessDied(pid, uid);
3344                } catch (RemoteException e) {
3345                }
3346            }
3347        }
3348        mProcessObservers.finishBroadcast();
3349    }
3350
3351    @Override
3352    public final int startActivity(IApplicationThread caller, String callingPackage,
3353            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3354            int startFlags, ProfilerInfo profilerInfo, Bundle options) {
3355        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3356            resultWho, requestCode, startFlags, profilerInfo, options,
3357            UserHandle.getCallingUserId());
3358    }
3359
3360    @Override
3361    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3362            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3363            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3364        enforceNotIsolatedCaller("startActivity");
3365        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3366                false, ALLOW_FULL_ONLY, "startActivity", null);
3367        // TODO: Switch to user app stacks here.
3368        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3369                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3370                profilerInfo, null, null, options, userId, null, null);
3371    }
3372
3373    @Override
3374    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
3375            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3376            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3377
3378        // This is very dangerous -- it allows you to perform a start activity (including
3379        // permission grants) as any app that may launch one of your own activities.  So
3380        // we will only allow this to be done from activities that are part of the core framework,
3381        // and then only when they are running as the system.
3382        final ActivityRecord sourceRecord;
3383        final int targetUid;
3384        final String targetPackage;
3385        synchronized (this) {
3386            if (resultTo == null) {
3387                throw new SecurityException("Must be called from an activity");
3388            }
3389            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
3390            if (sourceRecord == null) {
3391                throw new SecurityException("Called with bad activity token: " + resultTo);
3392            }
3393            if (!sourceRecord.info.packageName.equals("android")) {
3394                throw new SecurityException(
3395                        "Must be called from an activity that is declared in the android package");
3396            }
3397            if (sourceRecord.app == null) {
3398                throw new SecurityException("Called without a process attached to activity");
3399            }
3400            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
3401                // This is still okay, as long as this activity is running under the
3402                // uid of the original calling activity.
3403                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
3404                    throw new SecurityException(
3405                            "Calling activity in uid " + sourceRecord.app.uid
3406                                    + " must be system uid or original calling uid "
3407                                    + sourceRecord.launchedFromUid);
3408                }
3409            }
3410            targetUid = sourceRecord.launchedFromUid;
3411            targetPackage = sourceRecord.launchedFromPackage;
3412        }
3413
3414        if (userId == UserHandle.USER_NULL) {
3415            userId = UserHandle.getUserId(sourceRecord.app.uid);
3416        }
3417
3418        // TODO: Switch to user app stacks here.
3419        try {
3420            int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent,
3421                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
3422                    null, null, options, userId, null, null);
3423            return ret;
3424        } catch (SecurityException e) {
3425            // XXX need to figure out how to propagate to original app.
3426            // A SecurityException here is generally actually a fault of the original
3427            // calling activity (such as a fairly granting permissions), so propagate it
3428            // back to them.
3429            /*
3430            StringBuilder msg = new StringBuilder();
3431            msg.append("While launching");
3432            msg.append(intent.toString());
3433            msg.append(": ");
3434            msg.append(e.getMessage());
3435            */
3436            throw e;
3437        }
3438    }
3439
3440    @Override
3441    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3442            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3443            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3444        enforceNotIsolatedCaller("startActivityAndWait");
3445        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3446                false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
3447        WaitResult res = new WaitResult();
3448        // TODO: Switch to user app stacks here.
3449        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3450                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
3451                options, userId, null, null);
3452        return res;
3453    }
3454
3455    @Override
3456    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3457            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3458            int startFlags, Configuration config, Bundle options, int userId) {
3459        enforceNotIsolatedCaller("startActivityWithConfig");
3460        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3461                false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
3462        // TODO: Switch to user app stacks here.
3463        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3464                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3465                null, null, config, options, userId, null, null);
3466        return ret;
3467    }
3468
3469    @Override
3470    public int startActivityIntentSender(IApplicationThread caller,
3471            IntentSender intent, Intent fillInIntent, String resolvedType,
3472            IBinder resultTo, String resultWho, int requestCode,
3473            int flagsMask, int flagsValues, Bundle options) {
3474        enforceNotIsolatedCaller("startActivityIntentSender");
3475        // Refuse possible leaked file descriptors
3476        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3477            throw new IllegalArgumentException("File descriptors passed in Intent");
3478        }
3479
3480        IIntentSender sender = intent.getTarget();
3481        if (!(sender instanceof PendingIntentRecord)) {
3482            throw new IllegalArgumentException("Bad PendingIntent object");
3483        }
3484
3485        PendingIntentRecord pir = (PendingIntentRecord)sender;
3486
3487        synchronized (this) {
3488            // If this is coming from the currently resumed activity, it is
3489            // effectively saying that app switches are allowed at this point.
3490            final ActivityStack stack = getFocusedStack();
3491            if (stack.mResumedActivity != null &&
3492                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3493                mAppSwitchesAllowedTime = 0;
3494            }
3495        }
3496        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3497                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3498        return ret;
3499    }
3500
3501    @Override
3502    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3503            Intent intent, String resolvedType, IVoiceInteractionSession session,
3504            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
3505            Bundle options, int userId) {
3506        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3507                != PackageManager.PERMISSION_GRANTED) {
3508            String msg = "Permission Denial: startVoiceActivity() from pid="
3509                    + Binder.getCallingPid()
3510                    + ", uid=" + Binder.getCallingUid()
3511                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3512            Slog.w(TAG, msg);
3513            throw new SecurityException(msg);
3514        }
3515        if (session == null || interactor == null) {
3516            throw new NullPointerException("null session or interactor");
3517        }
3518        userId = handleIncomingUser(callingPid, callingUid, userId,
3519                false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
3520        // TODO: Switch to user app stacks here.
3521        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3522                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
3523                null, options, userId, null, null);
3524    }
3525
3526    @Override
3527    public boolean startNextMatchingActivity(IBinder callingActivity,
3528            Intent intent, Bundle options) {
3529        // Refuse possible leaked file descriptors
3530        if (intent != null && intent.hasFileDescriptors() == true) {
3531            throw new IllegalArgumentException("File descriptors passed in Intent");
3532        }
3533
3534        synchronized (this) {
3535            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3536            if (r == null) {
3537                ActivityOptions.abort(options);
3538                return false;
3539            }
3540            if (r.app == null || r.app.thread == null) {
3541                // The caller is not running...  d'oh!
3542                ActivityOptions.abort(options);
3543                return false;
3544            }
3545            intent = new Intent(intent);
3546            // The caller is not allowed to change the data.
3547            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3548            // And we are resetting to find the next component...
3549            intent.setComponent(null);
3550
3551            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3552
3553            ActivityInfo aInfo = null;
3554            try {
3555                List<ResolveInfo> resolves =
3556                    AppGlobals.getPackageManager().queryIntentActivities(
3557                            intent, r.resolvedType,
3558                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3559                            UserHandle.getCallingUserId());
3560
3561                // Look for the original activity in the list...
3562                final int N = resolves != null ? resolves.size() : 0;
3563                for (int i=0; i<N; i++) {
3564                    ResolveInfo rInfo = resolves.get(i);
3565                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3566                            && rInfo.activityInfo.name.equals(r.info.name)) {
3567                        // We found the current one...  the next matching is
3568                        // after it.
3569                        i++;
3570                        if (i<N) {
3571                            aInfo = resolves.get(i).activityInfo;
3572                        }
3573                        if (debug) {
3574                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3575                                    + "/" + r.info.name);
3576                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3577                                    + "/" + aInfo.name);
3578                        }
3579                        break;
3580                    }
3581                }
3582            } catch (RemoteException e) {
3583            }
3584
3585            if (aInfo == null) {
3586                // Nobody who is next!
3587                ActivityOptions.abort(options);
3588                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3589                return false;
3590            }
3591
3592            intent.setComponent(new ComponentName(
3593                    aInfo.applicationInfo.packageName, aInfo.name));
3594            intent.setFlags(intent.getFlags()&~(
3595                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3596                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3597                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3598                    Intent.FLAG_ACTIVITY_NEW_TASK));
3599
3600            // Okay now we need to start the new activity, replacing the
3601            // currently running activity.  This is a little tricky because
3602            // we want to start the new one as if the current one is finished,
3603            // but not finish the current one first so that there is no flicker.
3604            // And thus...
3605            final boolean wasFinishing = r.finishing;
3606            r.finishing = true;
3607
3608            // Propagate reply information over to the new activity.
3609            final ActivityRecord resultTo = r.resultTo;
3610            final String resultWho = r.resultWho;
3611            final int requestCode = r.requestCode;
3612            r.resultTo = null;
3613            if (resultTo != null) {
3614                resultTo.removeResultsLocked(r, resultWho, requestCode);
3615            }
3616
3617            final long origId = Binder.clearCallingIdentity();
3618            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3619                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3620                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage,
3621                    -1, r.launchedFromUid, 0, options, false, null, null, null);
3622            Binder.restoreCallingIdentity(origId);
3623
3624            r.finishing = wasFinishing;
3625            if (res != ActivityManager.START_SUCCESS) {
3626                return false;
3627            }
3628            return true;
3629        }
3630    }
3631
3632    @Override
3633    public final int startActivityFromRecents(int taskId, Bundle options) {
3634        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
3635            String msg = "Permission Denial: startActivityFromRecents called without " +
3636                    START_TASKS_FROM_RECENTS;
3637            Slog.w(TAG, msg);
3638            throw new SecurityException(msg);
3639        }
3640        return startActivityFromRecentsInner(taskId, options);
3641    }
3642
3643    final int startActivityFromRecentsInner(int taskId, Bundle options) {
3644        final TaskRecord task;
3645        final int callingUid;
3646        final String callingPackage;
3647        final Intent intent;
3648        final int userId;
3649        synchronized (this) {
3650            task = mRecentTasks.taskForIdLocked(taskId);
3651            if (task == null) {
3652                throw new IllegalArgumentException("Task " + taskId + " not found.");
3653            }
3654            if (task.getRootActivity() != null) {
3655                moveTaskToFrontLocked(task.taskId, 0, null);
3656                return ActivityManager.START_TASK_TO_FRONT;
3657            }
3658            callingUid = task.mCallingUid;
3659            callingPackage = task.mCallingPackage;
3660            intent = task.intent;
3661            intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
3662            userId = task.userId;
3663        }
3664        return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
3665                options, userId, null, task);
3666    }
3667
3668    final int startActivityInPackage(int uid, String callingPackage,
3669            Intent intent, String resolvedType, IBinder resultTo,
3670            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3671            IActivityContainer container, TaskRecord inTask) {
3672
3673        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3674                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3675
3676        // TODO: Switch to user app stacks here.
3677        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent,
3678                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3679                null, null, null, options, userId, container, inTask);
3680        return ret;
3681    }
3682
3683    @Override
3684    public final int startActivities(IApplicationThread caller, String callingPackage,
3685            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3686            int userId) {
3687        enforceNotIsolatedCaller("startActivities");
3688        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3689                false, ALLOW_FULL_ONLY, "startActivity", null);
3690        // TODO: Switch to user app stacks here.
3691        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3692                resolvedTypes, resultTo, options, userId);
3693        return ret;
3694    }
3695
3696    final int startActivitiesInPackage(int uid, String callingPackage,
3697            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3698            Bundle options, int userId) {
3699
3700        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3701                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3702        // TODO: Switch to user app stacks here.
3703        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3704                resultTo, options, userId);
3705        return ret;
3706    }
3707
3708    @Override
3709    public void reportActivityFullyDrawn(IBinder token) {
3710        synchronized (this) {
3711            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3712            if (r == null) {
3713                return;
3714            }
3715            r.reportFullyDrawnLocked();
3716        }
3717    }
3718
3719    @Override
3720    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
3721        synchronized (this) {
3722            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3723            if (r == null) {
3724                return;
3725            }
3726            final long origId = Binder.clearCallingIdentity();
3727            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
3728            Configuration config = mWindowManager.updateOrientationFromAppTokens(
3729                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
3730            if (config != null) {
3731                r.frozenBeforeDestroy = true;
3732                if (!updateConfigurationLocked(config, r, false, false)) {
3733                    mStackSupervisor.resumeTopActivitiesLocked();
3734                }
3735            }
3736            Binder.restoreCallingIdentity(origId);
3737        }
3738    }
3739
3740    @Override
3741    public int getRequestedOrientation(IBinder token) {
3742        synchronized (this) {
3743            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3744            if (r == null) {
3745                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3746            }
3747            return mWindowManager.getAppOrientation(r.appToken);
3748        }
3749    }
3750
3751    /**
3752     * This is the internal entry point for handling Activity.finish().
3753     *
3754     * @param token The Binder token referencing the Activity we want to finish.
3755     * @param resultCode Result code, if any, from this Activity.
3756     * @param resultData Result data (Intent), if any, from this Activity.
3757     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
3758     *            the root Activity in the task.
3759     *
3760     * @return Returns true if the activity successfully finished, or false if it is still running.
3761     */
3762    @Override
3763    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
3764            boolean finishTask) {
3765        // Refuse possible leaked file descriptors
3766        if (resultData != null && resultData.hasFileDescriptors() == true) {
3767            throw new IllegalArgumentException("File descriptors passed in Intent");
3768        }
3769
3770        synchronized(this) {
3771            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3772            if (r == null) {
3773                return true;
3774            }
3775            // Keep track of the root activity of the task before we finish it
3776            TaskRecord tr = r.task;
3777            ActivityRecord rootR = tr.getRootActivity();
3778            if (rootR == null) {
3779                Slog.w(TAG, "Finishing task with all activities already finished");
3780            }
3781            // Do not allow task to finish in Lock Task mode.
3782            if (tr == mStackSupervisor.mLockTaskModeTask) {
3783                if (rootR == r) {
3784                    Slog.i(TAG, "Not finishing task in lock task mode");
3785                    mStackSupervisor.showLockTaskToast();
3786                    return false;
3787                }
3788            }
3789            if (mController != null) {
3790                // Find the first activity that is not finishing.
3791                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
3792                if (next != null) {
3793                    // ask watcher if this is allowed
3794                    boolean resumeOK = true;
3795                    try {
3796                        resumeOK = mController.activityResuming(next.packageName);
3797                    } catch (RemoteException e) {
3798                        mController = null;
3799                        Watchdog.getInstance().setActivityController(null);
3800                    }
3801
3802                    if (!resumeOK) {
3803                        Slog.i(TAG, "Not finishing activity because controller resumed");
3804                        return false;
3805                    }
3806                }
3807            }
3808            final long origId = Binder.clearCallingIdentity();
3809            try {
3810                boolean res;
3811                if (finishTask && r == rootR) {
3812                    // If requested, remove the task that is associated to this activity only if it
3813                    // was the root activity in the task. The result code and data is ignored
3814                    // because we don't support returning them across task boundaries.
3815                    res = removeTaskByIdLocked(tr.taskId, false);
3816                    if (!res) {
3817                        Slog.i(TAG, "Removing task failed to finish activity");
3818                    }
3819                } else {
3820                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
3821                            resultData, "app-request", true);
3822                    if (!res) {
3823                        Slog.i(TAG, "Failed to finish by app-request");
3824                    }
3825                }
3826                return res;
3827            } finally {
3828                Binder.restoreCallingIdentity(origId);
3829            }
3830        }
3831    }
3832
3833    @Override
3834    public final void finishHeavyWeightApp() {
3835        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3836                != PackageManager.PERMISSION_GRANTED) {
3837            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
3838                    + Binder.getCallingPid()
3839                    + ", uid=" + Binder.getCallingUid()
3840                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3841            Slog.w(TAG, msg);
3842            throw new SecurityException(msg);
3843        }
3844
3845        synchronized(this) {
3846            if (mHeavyWeightProcess == null) {
3847                return;
3848            }
3849
3850            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
3851                    mHeavyWeightProcess.activities);
3852            for (int i=0; i<activities.size(); i++) {
3853                ActivityRecord r = activities.get(i);
3854                if (!r.finishing) {
3855                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
3856                            null, "finish-heavy", true);
3857                }
3858            }
3859
3860            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
3861                    mHeavyWeightProcess.userId, 0));
3862            mHeavyWeightProcess = null;
3863        }
3864    }
3865
3866    @Override
3867    public void crashApplication(int uid, int initialPid, String packageName,
3868            String message) {
3869        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3870                != PackageManager.PERMISSION_GRANTED) {
3871            String msg = "Permission Denial: crashApplication() from pid="
3872                    + Binder.getCallingPid()
3873                    + ", uid=" + Binder.getCallingUid()
3874                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3875            Slog.w(TAG, msg);
3876            throw new SecurityException(msg);
3877        }
3878
3879        synchronized(this) {
3880            ProcessRecord proc = null;
3881
3882            // Figure out which process to kill.  We don't trust that initialPid
3883            // still has any relation to current pids, so must scan through the
3884            // list.
3885            synchronized (mPidsSelfLocked) {
3886                for (int i=0; i<mPidsSelfLocked.size(); i++) {
3887                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
3888                    if (p.uid != uid) {
3889                        continue;
3890                    }
3891                    if (p.pid == initialPid) {
3892                        proc = p;
3893                        break;
3894                    }
3895                    if (p.pkgList.containsKey(packageName)) {
3896                        proc = p;
3897                    }
3898                }
3899            }
3900
3901            if (proc == null) {
3902                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
3903                        + " initialPid=" + initialPid
3904                        + " packageName=" + packageName);
3905                return;
3906            }
3907
3908            if (proc.thread != null) {
3909                if (proc.pid == Process.myPid()) {
3910                    Log.w(TAG, "crashApplication: trying to crash self!");
3911                    return;
3912                }
3913                long ident = Binder.clearCallingIdentity();
3914                try {
3915                    proc.thread.scheduleCrash(message);
3916                } catch (RemoteException e) {
3917                }
3918                Binder.restoreCallingIdentity(ident);
3919            }
3920        }
3921    }
3922
3923    @Override
3924    public final void finishSubActivity(IBinder token, String resultWho,
3925            int requestCode) {
3926        synchronized(this) {
3927            final long origId = Binder.clearCallingIdentity();
3928            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3929            if (r != null) {
3930                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
3931            }
3932            Binder.restoreCallingIdentity(origId);
3933        }
3934    }
3935
3936    @Override
3937    public boolean finishActivityAffinity(IBinder token) {
3938        synchronized(this) {
3939            final long origId = Binder.clearCallingIdentity();
3940            try {
3941                ActivityRecord r = ActivityRecord.isInStackLocked(token);
3942
3943                ActivityRecord rootR = r.task.getRootActivity();
3944                // Do not allow task to finish in Lock Task mode.
3945                if (r.task == mStackSupervisor.mLockTaskModeTask) {
3946                    if (rootR == r) {
3947                        mStackSupervisor.showLockTaskToast();
3948                        return false;
3949                    }
3950                }
3951                boolean res = false;
3952                if (r != null) {
3953                    res = r.task.stack.finishActivityAffinityLocked(r);
3954                }
3955                return res;
3956            } finally {
3957                Binder.restoreCallingIdentity(origId);
3958            }
3959        }
3960    }
3961
3962    @Override
3963    public void finishVoiceTask(IVoiceInteractionSession session) {
3964        synchronized(this) {
3965            final long origId = Binder.clearCallingIdentity();
3966            try {
3967                mStackSupervisor.finishVoiceTask(session);
3968            } finally {
3969                Binder.restoreCallingIdentity(origId);
3970            }
3971        }
3972
3973    }
3974
3975    @Override
3976    public boolean releaseActivityInstance(IBinder token) {
3977        synchronized(this) {
3978            final long origId = Binder.clearCallingIdentity();
3979            try {
3980                ActivityRecord r = ActivityRecord.isInStackLocked(token);
3981                if (r.task == null || r.task.stack == null) {
3982                    return false;
3983                }
3984                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
3985            } finally {
3986                Binder.restoreCallingIdentity(origId);
3987            }
3988        }
3989    }
3990
3991    @Override
3992    public void releaseSomeActivities(IApplicationThread appInt) {
3993        synchronized(this) {
3994            final long origId = Binder.clearCallingIdentity();
3995            try {
3996                ProcessRecord app = getRecordForAppLocked(appInt);
3997                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
3998            } finally {
3999                Binder.restoreCallingIdentity(origId);
4000            }
4001        }
4002    }
4003
4004    @Override
4005    public boolean willActivityBeVisible(IBinder token) {
4006        synchronized(this) {
4007            ActivityStack stack = ActivityRecord.getStackLocked(token);
4008            if (stack != null) {
4009                return stack.willActivityBeVisibleLocked(token);
4010            }
4011            return false;
4012        }
4013    }
4014
4015    @Override
4016    public void overridePendingTransition(IBinder token, String packageName,
4017            int enterAnim, int exitAnim) {
4018        synchronized(this) {
4019            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4020            if (self == null) {
4021                return;
4022            }
4023
4024            final long origId = Binder.clearCallingIdentity();
4025
4026            if (self.state == ActivityState.RESUMED
4027                    || self.state == ActivityState.PAUSING) {
4028                mWindowManager.overridePendingAppTransition(packageName,
4029                        enterAnim, exitAnim, null);
4030            }
4031
4032            Binder.restoreCallingIdentity(origId);
4033        }
4034    }
4035
4036    /**
4037     * Main function for removing an existing process from the activity manager
4038     * as a result of that process going away.  Clears out all connections
4039     * to the process.
4040     */
4041    private final void handleAppDiedLocked(ProcessRecord app,
4042            boolean restarting, boolean allowRestart) {
4043        int pid = app.pid;
4044        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4045        if (!kept && !restarting) {
4046            removeLruProcessLocked(app);
4047            if (pid > 0) {
4048                ProcessList.remove(pid);
4049            }
4050        }
4051
4052        if (mProfileProc == app) {
4053            clearProfilerLocked();
4054        }
4055
4056        // Remove this application's activities from active lists.
4057        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4058
4059        app.activities.clear();
4060
4061        if (app.instrumentationClass != null) {
4062            Slog.w(TAG, "Crash of app " + app.processName
4063                  + " running instrumentation " + app.instrumentationClass);
4064            Bundle info = new Bundle();
4065            info.putString("shortMsg", "Process crashed.");
4066            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4067        }
4068
4069        if (!restarting) {
4070            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
4071                // If there was nothing to resume, and we are not already
4072                // restarting this process, but there is a visible activity that
4073                // is hosted by the process...  then make sure all visible
4074                // activities are running, taking care of restarting this
4075                // process.
4076                if (hasVisibleActivities) {
4077                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
4078                }
4079            }
4080        }
4081    }
4082
4083    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4084        IBinder threadBinder = thread.asBinder();
4085        // Find the application record.
4086        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4087            ProcessRecord rec = mLruProcesses.get(i);
4088            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4089                return i;
4090            }
4091        }
4092        return -1;
4093    }
4094
4095    final ProcessRecord getRecordForAppLocked(
4096            IApplicationThread thread) {
4097        if (thread == null) {
4098            return null;
4099        }
4100
4101        int appIndex = getLRURecordIndexForAppLocked(thread);
4102        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4103    }
4104
4105    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4106        // If there are no longer any background processes running,
4107        // and the app that died was not running instrumentation,
4108        // then tell everyone we are now low on memory.
4109        boolean haveBg = false;
4110        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4111            ProcessRecord rec = mLruProcesses.get(i);
4112            if (rec.thread != null
4113                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4114                haveBg = true;
4115                break;
4116            }
4117        }
4118
4119        if (!haveBg) {
4120            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4121            if (doReport) {
4122                long now = SystemClock.uptimeMillis();
4123                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4124                    doReport = false;
4125                } else {
4126                    mLastMemUsageReportTime = now;
4127                }
4128            }
4129            final ArrayList<ProcessMemInfo> memInfos
4130                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4131            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4132            long now = SystemClock.uptimeMillis();
4133            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4134                ProcessRecord rec = mLruProcesses.get(i);
4135                if (rec == dyingProc || rec.thread == null) {
4136                    continue;
4137                }
4138                if (doReport) {
4139                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4140                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4141                }
4142                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4143                    // The low memory report is overriding any current
4144                    // state for a GC request.  Make sure to do
4145                    // heavy/important/visible/foreground processes first.
4146                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4147                        rec.lastRequestedGc = 0;
4148                    } else {
4149                        rec.lastRequestedGc = rec.lastLowMemory;
4150                    }
4151                    rec.reportLowMemory = true;
4152                    rec.lastLowMemory = now;
4153                    mProcessesToGc.remove(rec);
4154                    addProcessToGcListLocked(rec);
4155                }
4156            }
4157            if (doReport) {
4158                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4159                mHandler.sendMessage(msg);
4160            }
4161            scheduleAppGcsLocked();
4162        }
4163    }
4164
4165    final void appDiedLocked(ProcessRecord app) {
4166       appDiedLocked(app, app.pid, app.thread);
4167    }
4168
4169    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread) {
4170        // First check if this ProcessRecord is actually active for the pid.
4171        synchronized (mPidsSelfLocked) {
4172            ProcessRecord curProc = mPidsSelfLocked.get(pid);
4173            if (curProc != app) {
4174                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
4175                return;
4176            }
4177        }
4178
4179        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4180        synchronized (stats) {
4181            stats.noteProcessDiedLocked(app.info.uid, pid);
4182        }
4183
4184        if (!app.killed) {
4185            Process.killProcessQuiet(pid);
4186            Process.killProcessGroup(app.info.uid, pid);
4187            app.killed = true;
4188        }
4189
4190        // Clean up already done if the process has been re-started.
4191        if (app.pid == pid && app.thread != null &&
4192                app.thread.asBinder() == thread.asBinder()) {
4193            boolean doLowMem = app.instrumentationClass == null;
4194            boolean doOomAdj = doLowMem;
4195            if (!app.killedByAm) {
4196                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4197                        + ") has died");
4198                mAllowLowerMemLevel = true;
4199            } else {
4200                // Note that we always want to do oom adj to update our state with the
4201                // new number of procs.
4202                mAllowLowerMemLevel = false;
4203                doLowMem = false;
4204            }
4205            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4206            if (DEBUG_CLEANUP) Slog.v(
4207                TAG, "Dying app: " + app + ", pid: " + pid
4208                + ", thread: " + thread.asBinder());
4209            handleAppDiedLocked(app, false, true);
4210
4211            if (doOomAdj) {
4212                updateOomAdjLocked();
4213            }
4214            if (doLowMem) {
4215                doLowMemReportIfNeededLocked(app);
4216            }
4217        } else if (app.pid != pid) {
4218            // A new process has already been started.
4219            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4220                    + ") has died and restarted (pid " + app.pid + ").");
4221            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4222        } else if (DEBUG_PROCESSES) {
4223            Slog.d(TAG, "Received spurious death notification for thread "
4224                    + thread.asBinder());
4225        }
4226    }
4227
4228    /**
4229     * If a stack trace dump file is configured, dump process stack traces.
4230     * @param clearTraces causes the dump file to be erased prior to the new
4231     *    traces being written, if true; when false, the new traces will be
4232     *    appended to any existing file content.
4233     * @param firstPids of dalvik VM processes to dump stack traces for first
4234     * @param lastPids of dalvik VM processes to dump stack traces for last
4235     * @param nativeProcs optional list of native process names to dump stack crawls
4236     * @return file containing stack traces, or null if no dump file is configured
4237     */
4238    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4239            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4240        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4241        if (tracesPath == null || tracesPath.length() == 0) {
4242            return null;
4243        }
4244
4245        File tracesFile = new File(tracesPath);
4246        try {
4247            File tracesDir = tracesFile.getParentFile();
4248            if (!tracesDir.exists()) {
4249                tracesDir.mkdirs();
4250                if (!SELinux.restorecon(tracesDir)) {
4251                    return null;
4252                }
4253            }
4254            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4255
4256            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4257            tracesFile.createNewFile();
4258            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4259        } catch (IOException e) {
4260            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4261            return null;
4262        }
4263
4264        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4265        return tracesFile;
4266    }
4267
4268    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4269            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4270        // Use a FileObserver to detect when traces finish writing.
4271        // The order of traces is considered important to maintain for legibility.
4272        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4273            @Override
4274            public synchronized void onEvent(int event, String path) { notify(); }
4275        };
4276
4277        try {
4278            observer.startWatching();
4279
4280            // First collect all of the stacks of the most important pids.
4281            if (firstPids != null) {
4282                try {
4283                    int num = firstPids.size();
4284                    for (int i = 0; i < num; i++) {
4285                        synchronized (observer) {
4286                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4287                            observer.wait(200);  // Wait for write-close, give up after 200msec
4288                        }
4289                    }
4290                } catch (InterruptedException e) {
4291                    Slog.wtf(TAG, e);
4292                }
4293            }
4294
4295            // Next collect the stacks of the native pids
4296            if (nativeProcs != null) {
4297                int[] pids = Process.getPidsForCommands(nativeProcs);
4298                if (pids != null) {
4299                    for (int pid : pids) {
4300                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4301                    }
4302                }
4303            }
4304
4305            // Lastly, measure CPU usage.
4306            if (processCpuTracker != null) {
4307                processCpuTracker.init();
4308                System.gc();
4309                processCpuTracker.update();
4310                try {
4311                    synchronized (processCpuTracker) {
4312                        processCpuTracker.wait(500); // measure over 1/2 second.
4313                    }
4314                } catch (InterruptedException e) {
4315                }
4316                processCpuTracker.update();
4317
4318                // We'll take the stack crawls of just the top apps using CPU.
4319                final int N = processCpuTracker.countWorkingStats();
4320                int numProcs = 0;
4321                for (int i=0; i<N && numProcs<5; i++) {
4322                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4323                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4324                        numProcs++;
4325                        try {
4326                            synchronized (observer) {
4327                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4328                                observer.wait(200);  // Wait for write-close, give up after 200msec
4329                            }
4330                        } catch (InterruptedException e) {
4331                            Slog.wtf(TAG, e);
4332                        }
4333
4334                    }
4335                }
4336            }
4337        } finally {
4338            observer.stopWatching();
4339        }
4340    }
4341
4342    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4343        if (true || IS_USER_BUILD) {
4344            return;
4345        }
4346        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4347        if (tracesPath == null || tracesPath.length() == 0) {
4348            return;
4349        }
4350
4351        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4352        StrictMode.allowThreadDiskWrites();
4353        try {
4354            final File tracesFile = new File(tracesPath);
4355            final File tracesDir = tracesFile.getParentFile();
4356            final File tracesTmp = new File(tracesDir, "__tmp__");
4357            try {
4358                if (!tracesDir.exists()) {
4359                    tracesDir.mkdirs();
4360                    if (!SELinux.restorecon(tracesDir.getPath())) {
4361                        return;
4362                    }
4363                }
4364                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4365
4366                if (tracesFile.exists()) {
4367                    tracesTmp.delete();
4368                    tracesFile.renameTo(tracesTmp);
4369                }
4370                StringBuilder sb = new StringBuilder();
4371                Time tobj = new Time();
4372                tobj.set(System.currentTimeMillis());
4373                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4374                sb.append(": ");
4375                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4376                sb.append(" since ");
4377                sb.append(msg);
4378                FileOutputStream fos = new FileOutputStream(tracesFile);
4379                fos.write(sb.toString().getBytes());
4380                if (app == null) {
4381                    fos.write("\n*** No application process!".getBytes());
4382                }
4383                fos.close();
4384                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4385            } catch (IOException e) {
4386                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4387                return;
4388            }
4389
4390            if (app != null) {
4391                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4392                firstPids.add(app.pid);
4393                dumpStackTraces(tracesPath, firstPids, null, null, null);
4394            }
4395
4396            File lastTracesFile = null;
4397            File curTracesFile = null;
4398            for (int i=9; i>=0; i--) {
4399                String name = String.format(Locale.US, "slow%02d.txt", i);
4400                curTracesFile = new File(tracesDir, name);
4401                if (curTracesFile.exists()) {
4402                    if (lastTracesFile != null) {
4403                        curTracesFile.renameTo(lastTracesFile);
4404                    } else {
4405                        curTracesFile.delete();
4406                    }
4407                }
4408                lastTracesFile = curTracesFile;
4409            }
4410            tracesFile.renameTo(curTracesFile);
4411            if (tracesTmp.exists()) {
4412                tracesTmp.renameTo(tracesFile);
4413            }
4414        } finally {
4415            StrictMode.setThreadPolicy(oldPolicy);
4416        }
4417    }
4418
4419    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4420            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4421        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4422        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4423
4424        if (mController != null) {
4425            try {
4426                // 0 == continue, -1 = kill process immediately
4427                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4428                if (res < 0 && app.pid != MY_PID) {
4429                    app.kill("anr", true);
4430                }
4431            } catch (RemoteException e) {
4432                mController = null;
4433                Watchdog.getInstance().setActivityController(null);
4434            }
4435        }
4436
4437        long anrTime = SystemClock.uptimeMillis();
4438        if (MONITOR_CPU_USAGE) {
4439            updateCpuStatsNow();
4440        }
4441
4442        synchronized (this) {
4443            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4444            if (mShuttingDown) {
4445                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4446                return;
4447            } else if (app.notResponding) {
4448                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4449                return;
4450            } else if (app.crashing) {
4451                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4452                return;
4453            }
4454
4455            // In case we come through here for the same app before completing
4456            // this one, mark as anring now so we will bail out.
4457            app.notResponding = true;
4458
4459            // Log the ANR to the event log.
4460            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4461                    app.processName, app.info.flags, annotation);
4462
4463            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4464            firstPids.add(app.pid);
4465
4466            int parentPid = app.pid;
4467            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4468            if (parentPid != app.pid) firstPids.add(parentPid);
4469
4470            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4471
4472            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4473                ProcessRecord r = mLruProcesses.get(i);
4474                if (r != null && r.thread != null) {
4475                    int pid = r.pid;
4476                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4477                        if (r.persistent) {
4478                            firstPids.add(pid);
4479                        } else {
4480                            lastPids.put(pid, Boolean.TRUE);
4481                        }
4482                    }
4483                }
4484            }
4485        }
4486
4487        // Log the ANR to the main log.
4488        StringBuilder info = new StringBuilder();
4489        info.setLength(0);
4490        info.append("ANR in ").append(app.processName);
4491        if (activity != null && activity.shortComponentName != null) {
4492            info.append(" (").append(activity.shortComponentName).append(")");
4493        }
4494        info.append("\n");
4495        info.append("PID: ").append(app.pid).append("\n");
4496        if (annotation != null) {
4497            info.append("Reason: ").append(annotation).append("\n");
4498        }
4499        if (parent != null && parent != activity) {
4500            info.append("Parent: ").append(parent.shortComponentName).append("\n");
4501        }
4502
4503        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4504
4505        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4506                NATIVE_STACKS_OF_INTEREST);
4507
4508        String cpuInfo = null;
4509        if (MONITOR_CPU_USAGE) {
4510            updateCpuStatsNow();
4511            synchronized (mProcessCpuTracker) {
4512                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4513            }
4514            info.append(processCpuTracker.printCurrentLoad());
4515            info.append(cpuInfo);
4516        }
4517
4518        info.append(processCpuTracker.printCurrentState(anrTime));
4519
4520        Slog.e(TAG, info.toString());
4521        if (tracesFile == null) {
4522            // There is no trace file, so dump (only) the alleged culprit's threads to the log
4523            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4524        }
4525
4526        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
4527                cpuInfo, tracesFile, null);
4528
4529        if (mController != null) {
4530            try {
4531                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
4532                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
4533                if (res != 0) {
4534                    if (res < 0 && app.pid != MY_PID) {
4535                        app.kill("anr", true);
4536                    } else {
4537                        synchronized (this) {
4538                            mServices.scheduleServiceTimeoutLocked(app);
4539                        }
4540                    }
4541                    return;
4542                }
4543            } catch (RemoteException e) {
4544                mController = null;
4545                Watchdog.getInstance().setActivityController(null);
4546            }
4547        }
4548
4549        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
4550        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
4551                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
4552
4553        synchronized (this) {
4554            mBatteryStatsService.noteProcessAnr(app.processName, app.uid);
4555
4556            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
4557                app.kill("bg anr", true);
4558                return;
4559            }
4560
4561            // Set the app's notResponding state, and look up the errorReportReceiver
4562            makeAppNotRespondingLocked(app,
4563                    activity != null ? activity.shortComponentName : null,
4564                    annotation != null ? "ANR " + annotation : "ANR",
4565                    info.toString());
4566
4567            // Bring up the infamous App Not Responding dialog
4568            Message msg = Message.obtain();
4569            HashMap<String, Object> map = new HashMap<String, Object>();
4570            msg.what = SHOW_NOT_RESPONDING_MSG;
4571            msg.obj = map;
4572            msg.arg1 = aboveSystem ? 1 : 0;
4573            map.put("app", app);
4574            if (activity != null) {
4575                map.put("activity", activity);
4576            }
4577
4578            mHandler.sendMessage(msg);
4579        }
4580    }
4581
4582    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
4583        if (!mLaunchWarningShown) {
4584            mLaunchWarningShown = true;
4585            mHandler.post(new Runnable() {
4586                @Override
4587                public void run() {
4588                    synchronized (ActivityManagerService.this) {
4589                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
4590                        d.show();
4591                        mHandler.postDelayed(new Runnable() {
4592                            @Override
4593                            public void run() {
4594                                synchronized (ActivityManagerService.this) {
4595                                    d.dismiss();
4596                                    mLaunchWarningShown = false;
4597                                }
4598                            }
4599                        }, 4000);
4600                    }
4601                }
4602            });
4603        }
4604    }
4605
4606    @Override
4607    public boolean clearApplicationUserData(final String packageName,
4608            final IPackageDataObserver observer, int userId) {
4609        enforceNotIsolatedCaller("clearApplicationUserData");
4610        int uid = Binder.getCallingUid();
4611        int pid = Binder.getCallingPid();
4612        userId = handleIncomingUser(pid, uid,
4613                userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
4614        long callingId = Binder.clearCallingIdentity();
4615        try {
4616            IPackageManager pm = AppGlobals.getPackageManager();
4617            int pkgUid = -1;
4618            synchronized(this) {
4619                try {
4620                    pkgUid = pm.getPackageUid(packageName, userId);
4621                } catch (RemoteException e) {
4622                }
4623                if (pkgUid == -1) {
4624                    Slog.w(TAG, "Invalid packageName: " + packageName);
4625                    if (observer != null) {
4626                        try {
4627                            observer.onRemoveCompleted(packageName, false);
4628                        } catch (RemoteException e) {
4629                            Slog.i(TAG, "Observer no longer exists.");
4630                        }
4631                    }
4632                    return false;
4633                }
4634                if (uid == pkgUid || checkComponentPermission(
4635                        android.Manifest.permission.CLEAR_APP_USER_DATA,
4636                        pid, uid, -1, true)
4637                        == PackageManager.PERMISSION_GRANTED) {
4638                    forceStopPackageLocked(packageName, pkgUid, "clear data");
4639                } else {
4640                    throw new SecurityException("PID " + pid + " does not have permission "
4641                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
4642                                    + " of package " + packageName);
4643                }
4644
4645                // Remove all tasks match the cleared application package and user
4646                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
4647                    final TaskRecord tr = mRecentTasks.get(i);
4648                    final String taskPackageName =
4649                            tr.getBaseIntent().getComponent().getPackageName();
4650                    if (tr.userId != userId) continue;
4651                    if (!taskPackageName.equals(packageName)) continue;
4652                    removeTaskByIdLocked(tr.taskId, false);
4653                }
4654            }
4655
4656            try {
4657                // Clear application user data
4658                pm.clearApplicationUserData(packageName, observer, userId);
4659
4660                synchronized(this) {
4661                    // Remove all permissions granted from/to this package
4662                    removeUriPermissionsForPackageLocked(packageName, userId, true);
4663                }
4664
4665                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
4666                        Uri.fromParts("package", packageName, null));
4667                intent.putExtra(Intent.EXTRA_UID, pkgUid);
4668                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
4669                        null, null, 0, null, null, null, false, false, userId);
4670            } catch (RemoteException e) {
4671            }
4672        } finally {
4673            Binder.restoreCallingIdentity(callingId);
4674        }
4675        return true;
4676    }
4677
4678    @Override
4679    public void killBackgroundProcesses(final String packageName, int userId) {
4680        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4681                != PackageManager.PERMISSION_GRANTED &&
4682                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
4683                        != PackageManager.PERMISSION_GRANTED) {
4684            String msg = "Permission Denial: killBackgroundProcesses() from pid="
4685                    + Binder.getCallingPid()
4686                    + ", uid=" + Binder.getCallingUid()
4687                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4688            Slog.w(TAG, msg);
4689            throw new SecurityException(msg);
4690        }
4691
4692        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4693                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
4694        long callingId = Binder.clearCallingIdentity();
4695        try {
4696            IPackageManager pm = AppGlobals.getPackageManager();
4697            synchronized(this) {
4698                int appId = -1;
4699                try {
4700                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
4701                } catch (RemoteException e) {
4702                }
4703                if (appId == -1) {
4704                    Slog.w(TAG, "Invalid packageName: " + packageName);
4705                    return;
4706                }
4707                killPackageProcessesLocked(packageName, appId, userId,
4708                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
4709            }
4710        } finally {
4711            Binder.restoreCallingIdentity(callingId);
4712        }
4713    }
4714
4715    @Override
4716    public void killAllBackgroundProcesses() {
4717        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4718                != PackageManager.PERMISSION_GRANTED) {
4719            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
4720                    + Binder.getCallingPid()
4721                    + ", uid=" + Binder.getCallingUid()
4722                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4723            Slog.w(TAG, msg);
4724            throw new SecurityException(msg);
4725        }
4726
4727        long callingId = Binder.clearCallingIdentity();
4728        try {
4729            synchronized(this) {
4730                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4731                final int NP = mProcessNames.getMap().size();
4732                for (int ip=0; ip<NP; ip++) {
4733                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4734                    final int NA = apps.size();
4735                    for (int ia=0; ia<NA; ia++) {
4736                        ProcessRecord app = apps.valueAt(ia);
4737                        if (app.persistent) {
4738                            // we don't kill persistent processes
4739                            continue;
4740                        }
4741                        if (app.removed) {
4742                            procs.add(app);
4743                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
4744                            app.removed = true;
4745                            procs.add(app);
4746                        }
4747                    }
4748                }
4749
4750                int N = procs.size();
4751                for (int i=0; i<N; i++) {
4752                    removeProcessLocked(procs.get(i), false, true, "kill all background");
4753                }
4754                mAllowLowerMemLevel = true;
4755                updateOomAdjLocked();
4756                doLowMemReportIfNeededLocked(null);
4757            }
4758        } finally {
4759            Binder.restoreCallingIdentity(callingId);
4760        }
4761    }
4762
4763    @Override
4764    public void forceStopPackage(final String packageName, int userId) {
4765        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4766                != PackageManager.PERMISSION_GRANTED) {
4767            String msg = "Permission Denial: forceStopPackage() from pid="
4768                    + Binder.getCallingPid()
4769                    + ", uid=" + Binder.getCallingUid()
4770                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4771            Slog.w(TAG, msg);
4772            throw new SecurityException(msg);
4773        }
4774        final int callingPid = Binder.getCallingPid();
4775        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
4776                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
4777        long callingId = Binder.clearCallingIdentity();
4778        try {
4779            IPackageManager pm = AppGlobals.getPackageManager();
4780            synchronized(this) {
4781                int[] users = userId == UserHandle.USER_ALL
4782                        ? getUsersLocked() : new int[] { userId };
4783                for (int user : users) {
4784                    int pkgUid = -1;
4785                    try {
4786                        pkgUid = pm.getPackageUid(packageName, user);
4787                    } catch (RemoteException e) {
4788                    }
4789                    if (pkgUid == -1) {
4790                        Slog.w(TAG, "Invalid packageName: " + packageName);
4791                        continue;
4792                    }
4793                    try {
4794                        pm.setPackageStoppedState(packageName, true, user);
4795                    } catch (RemoteException e) {
4796                    } catch (IllegalArgumentException e) {
4797                        Slog.w(TAG, "Failed trying to unstop package "
4798                                + packageName + ": " + e);
4799                    }
4800                    if (isUserRunningLocked(user, false)) {
4801                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
4802                    }
4803                }
4804            }
4805        } finally {
4806            Binder.restoreCallingIdentity(callingId);
4807        }
4808    }
4809
4810    @Override
4811    public void addPackageDependency(String packageName) {
4812        synchronized (this) {
4813            int callingPid = Binder.getCallingPid();
4814            if (callingPid == Process.myPid()) {
4815                //  Yeah, um, no.
4816                return;
4817            }
4818            ProcessRecord proc;
4819            synchronized (mPidsSelfLocked) {
4820                proc = mPidsSelfLocked.get(Binder.getCallingPid());
4821            }
4822            if (proc != null) {
4823                if (proc.pkgDeps == null) {
4824                    proc.pkgDeps = new ArraySet<String>(1);
4825                }
4826                proc.pkgDeps.add(packageName);
4827            }
4828        }
4829    }
4830
4831    /*
4832     * The pkg name and app id have to be specified.
4833     */
4834    @Override
4835    public void killApplicationWithAppId(String pkg, int appid, String reason) {
4836        if (pkg == null) {
4837            return;
4838        }
4839        // Make sure the uid is valid.
4840        if (appid < 0) {
4841            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
4842            return;
4843        }
4844        int callerUid = Binder.getCallingUid();
4845        // Only the system server can kill an application
4846        if (callerUid == Process.SYSTEM_UID) {
4847            // Post an aysnc message to kill the application
4848            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
4849            msg.arg1 = appid;
4850            msg.arg2 = 0;
4851            Bundle bundle = new Bundle();
4852            bundle.putString("pkg", pkg);
4853            bundle.putString("reason", reason);
4854            msg.obj = bundle;
4855            mHandler.sendMessage(msg);
4856        } else {
4857            throw new SecurityException(callerUid + " cannot kill pkg: " +
4858                    pkg);
4859        }
4860    }
4861
4862    @Override
4863    public void closeSystemDialogs(String reason) {
4864        enforceNotIsolatedCaller("closeSystemDialogs");
4865
4866        final int pid = Binder.getCallingPid();
4867        final int uid = Binder.getCallingUid();
4868        final long origId = Binder.clearCallingIdentity();
4869        try {
4870            synchronized (this) {
4871                // Only allow this from foreground processes, so that background
4872                // applications can't abuse it to prevent system UI from being shown.
4873                if (uid >= Process.FIRST_APPLICATION_UID) {
4874                    ProcessRecord proc;
4875                    synchronized (mPidsSelfLocked) {
4876                        proc = mPidsSelfLocked.get(pid);
4877                    }
4878                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
4879                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
4880                                + " from background process " + proc);
4881                        return;
4882                    }
4883                }
4884                closeSystemDialogsLocked(reason);
4885            }
4886        } finally {
4887            Binder.restoreCallingIdentity(origId);
4888        }
4889    }
4890
4891    void closeSystemDialogsLocked(String reason) {
4892        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
4893        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4894                | Intent.FLAG_RECEIVER_FOREGROUND);
4895        if (reason != null) {
4896            intent.putExtra("reason", reason);
4897        }
4898        mWindowManager.closeSystemDialogs(reason);
4899
4900        mStackSupervisor.closeSystemDialogsLocked();
4901
4902        broadcastIntentLocked(null, null, intent, null,
4903                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
4904                Process.SYSTEM_UID, UserHandle.USER_ALL);
4905    }
4906
4907    @Override
4908    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
4909        enforceNotIsolatedCaller("getProcessMemoryInfo");
4910        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
4911        for (int i=pids.length-1; i>=0; i--) {
4912            ProcessRecord proc;
4913            int oomAdj;
4914            synchronized (this) {
4915                synchronized (mPidsSelfLocked) {
4916                    proc = mPidsSelfLocked.get(pids[i]);
4917                    oomAdj = proc != null ? proc.setAdj : 0;
4918                }
4919            }
4920            infos[i] = new Debug.MemoryInfo();
4921            Debug.getMemoryInfo(pids[i], infos[i]);
4922            if (proc != null) {
4923                synchronized (this) {
4924                    if (proc.thread != null && proc.setAdj == oomAdj) {
4925                        // Record this for posterity if the process has been stable.
4926                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
4927                                infos[i].getTotalUss(), false, proc.pkgList);
4928                    }
4929                }
4930            }
4931        }
4932        return infos;
4933    }
4934
4935    @Override
4936    public long[] getProcessPss(int[] pids) {
4937        enforceNotIsolatedCaller("getProcessPss");
4938        long[] pss = new long[pids.length];
4939        for (int i=pids.length-1; i>=0; i--) {
4940            ProcessRecord proc;
4941            int oomAdj;
4942            synchronized (this) {
4943                synchronized (mPidsSelfLocked) {
4944                    proc = mPidsSelfLocked.get(pids[i]);
4945                    oomAdj = proc != null ? proc.setAdj : 0;
4946                }
4947            }
4948            long[] tmpUss = new long[1];
4949            pss[i] = Debug.getPss(pids[i], tmpUss, null);
4950            if (proc != null) {
4951                synchronized (this) {
4952                    if (proc.thread != null && proc.setAdj == oomAdj) {
4953                        // Record this for posterity if the process has been stable.
4954                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
4955                    }
4956                }
4957            }
4958        }
4959        return pss;
4960    }
4961
4962    @Override
4963    public void killApplicationProcess(String processName, int uid) {
4964        if (processName == null) {
4965            return;
4966        }
4967
4968        int callerUid = Binder.getCallingUid();
4969        // Only the system server can kill an application
4970        if (callerUid == Process.SYSTEM_UID) {
4971            synchronized (this) {
4972                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
4973                if (app != null && app.thread != null) {
4974                    try {
4975                        app.thread.scheduleSuicide();
4976                    } catch (RemoteException e) {
4977                        // If the other end already died, then our work here is done.
4978                    }
4979                } else {
4980                    Slog.w(TAG, "Process/uid not found attempting kill of "
4981                            + processName + " / " + uid);
4982                }
4983            }
4984        } else {
4985            throw new SecurityException(callerUid + " cannot kill app process: " +
4986                    processName);
4987        }
4988    }
4989
4990    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
4991        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
4992                false, true, false, false, UserHandle.getUserId(uid), reason);
4993        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
4994                Uri.fromParts("package", packageName, null));
4995        if (!mProcessesReady) {
4996            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4997                    | Intent.FLAG_RECEIVER_FOREGROUND);
4998        }
4999        intent.putExtra(Intent.EXTRA_UID, uid);
5000        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5001        broadcastIntentLocked(null, null, intent,
5002                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5003                false, false,
5004                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5005    }
5006
5007    private void forceStopUserLocked(int userId, String reason) {
5008        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
5009        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
5010        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5011                | Intent.FLAG_RECEIVER_FOREGROUND);
5012        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5013        broadcastIntentLocked(null, null, intent,
5014                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5015                false, false,
5016                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
5017    }
5018
5019    private final boolean killPackageProcessesLocked(String packageName, int appId,
5020            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5021            boolean doit, boolean evenPersistent, String reason) {
5022        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5023
5024        // Remove all processes this package may have touched: all with the
5025        // same UID (except for the system or root user), and all whose name
5026        // matches the package name.
5027        final int NP = mProcessNames.getMap().size();
5028        for (int ip=0; ip<NP; ip++) {
5029            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5030            final int NA = apps.size();
5031            for (int ia=0; ia<NA; ia++) {
5032                ProcessRecord app = apps.valueAt(ia);
5033                if (app.persistent && !evenPersistent) {
5034                    // we don't kill persistent processes
5035                    continue;
5036                }
5037                if (app.removed) {
5038                    if (doit) {
5039                        procs.add(app);
5040                    }
5041                    continue;
5042                }
5043
5044                // Skip process if it doesn't meet our oom adj requirement.
5045                if (app.setAdj < minOomAdj) {
5046                    continue;
5047                }
5048
5049                // If no package is specified, we call all processes under the
5050                // give user id.
5051                if (packageName == null) {
5052                    if (app.userId != userId) {
5053                        continue;
5054                    }
5055                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5056                        continue;
5057                    }
5058                // Package has been specified, we want to hit all processes
5059                // that match it.  We need to qualify this by the processes
5060                // that are running under the specified app and user ID.
5061                } else {
5062                    final boolean isDep = app.pkgDeps != null
5063                            && app.pkgDeps.contains(packageName);
5064                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5065                        continue;
5066                    }
5067                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5068                        continue;
5069                    }
5070                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5071                        continue;
5072                    }
5073                }
5074
5075                // Process has passed all conditions, kill it!
5076                if (!doit) {
5077                    return true;
5078                }
5079                app.removed = true;
5080                procs.add(app);
5081            }
5082        }
5083
5084        int N = procs.size();
5085        for (int i=0; i<N; i++) {
5086            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5087        }
5088        updateOomAdjLocked();
5089        return N > 0;
5090    }
5091
5092    private final boolean forceStopPackageLocked(String name, int appId,
5093            boolean callerWillRestart, boolean purgeCache, boolean doit,
5094            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5095        int i;
5096        int N;
5097
5098        if (userId == UserHandle.USER_ALL && name == null) {
5099            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5100        }
5101
5102        if (appId < 0 && name != null) {
5103            try {
5104                appId = UserHandle.getAppId(
5105                        AppGlobals.getPackageManager().getPackageUid(name, 0));
5106            } catch (RemoteException e) {
5107            }
5108        }
5109
5110        if (doit) {
5111            if (name != null) {
5112                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
5113                        + " user=" + userId + ": " + reason);
5114            } else {
5115                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5116            }
5117
5118            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5119            for (int ip=pmap.size()-1; ip>=0; ip--) {
5120                SparseArray<Long> ba = pmap.valueAt(ip);
5121                for (i=ba.size()-1; i>=0; i--) {
5122                    boolean remove = false;
5123                    final int entUid = ba.keyAt(i);
5124                    if (name != null) {
5125                        if (userId == UserHandle.USER_ALL) {
5126                            if (UserHandle.getAppId(entUid) == appId) {
5127                                remove = true;
5128                            }
5129                        } else {
5130                            if (entUid == UserHandle.getUid(userId, appId)) {
5131                                remove = true;
5132                            }
5133                        }
5134                    } else if (UserHandle.getUserId(entUid) == userId) {
5135                        remove = true;
5136                    }
5137                    if (remove) {
5138                        ba.removeAt(i);
5139                    }
5140                }
5141                if (ba.size() == 0) {
5142                    pmap.removeAt(ip);
5143                }
5144            }
5145        }
5146
5147        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
5148                -100, callerWillRestart, true, doit, evenPersistent,
5149                name == null ? ("stop user " + userId) : ("stop " + name));
5150
5151        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
5152            if (!doit) {
5153                return true;
5154            }
5155            didSomething = true;
5156        }
5157
5158        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
5159            if (!doit) {
5160                return true;
5161            }
5162            didSomething = true;
5163        }
5164
5165        if (name == null) {
5166            // Remove all sticky broadcasts from this user.
5167            mStickyBroadcasts.remove(userId);
5168        }
5169
5170        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
5171        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
5172                userId, providers)) {
5173            if (!doit) {
5174                return true;
5175            }
5176            didSomething = true;
5177        }
5178        N = providers.size();
5179        for (i=0; i<N; i++) {
5180            removeDyingProviderLocked(null, providers.get(i), true);
5181        }
5182
5183        // Remove transient permissions granted from/to this package/user
5184        removeUriPermissionsForPackageLocked(name, userId, false);
5185
5186        if (name == null || uninstalling) {
5187            // Remove pending intents.  For now we only do this when force
5188            // stopping users, because we have some problems when doing this
5189            // for packages -- app widgets are not currently cleaned up for
5190            // such packages, so they can be left with bad pending intents.
5191            if (mIntentSenderRecords.size() > 0) {
5192                Iterator<WeakReference<PendingIntentRecord>> it
5193                        = mIntentSenderRecords.values().iterator();
5194                while (it.hasNext()) {
5195                    WeakReference<PendingIntentRecord> wpir = it.next();
5196                    if (wpir == null) {
5197                        it.remove();
5198                        continue;
5199                    }
5200                    PendingIntentRecord pir = wpir.get();
5201                    if (pir == null) {
5202                        it.remove();
5203                        continue;
5204                    }
5205                    if (name == null) {
5206                        // Stopping user, remove all objects for the user.
5207                        if (pir.key.userId != userId) {
5208                            // Not the same user, skip it.
5209                            continue;
5210                        }
5211                    } else {
5212                        if (UserHandle.getAppId(pir.uid) != appId) {
5213                            // Different app id, skip it.
5214                            continue;
5215                        }
5216                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5217                            // Different user, skip it.
5218                            continue;
5219                        }
5220                        if (!pir.key.packageName.equals(name)) {
5221                            // Different package, skip it.
5222                            continue;
5223                        }
5224                    }
5225                    if (!doit) {
5226                        return true;
5227                    }
5228                    didSomething = true;
5229                    it.remove();
5230                    pir.canceled = true;
5231                    if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
5232                        pir.key.activity.pendingResults.remove(pir.ref);
5233                    }
5234                }
5235            }
5236        }
5237
5238        if (doit) {
5239            if (purgeCache && name != null) {
5240                AttributeCache ac = AttributeCache.instance();
5241                if (ac != null) {
5242                    ac.removePackage(name);
5243                }
5244            }
5245            if (mBooted) {
5246                mStackSupervisor.resumeTopActivitiesLocked();
5247                mStackSupervisor.scheduleIdleLocked();
5248            }
5249        }
5250
5251        return didSomething;
5252    }
5253
5254    private final boolean removeProcessLocked(ProcessRecord app,
5255            boolean callerWillRestart, boolean allowRestart, String reason) {
5256        final String name = app.processName;
5257        final int uid = app.uid;
5258        if (DEBUG_PROCESSES) Slog.d(
5259            TAG, "Force removing proc " + app.toShortString() + " (" + name
5260            + "/" + uid + ")");
5261
5262        mProcessNames.remove(name, uid);
5263        mIsolatedProcesses.remove(app.uid);
5264        if (mHeavyWeightProcess == app) {
5265            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5266                    mHeavyWeightProcess.userId, 0));
5267            mHeavyWeightProcess = null;
5268        }
5269        boolean needRestart = false;
5270        if (app.pid > 0 && app.pid != MY_PID) {
5271            int pid = app.pid;
5272            synchronized (mPidsSelfLocked) {
5273                mPidsSelfLocked.remove(pid);
5274                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5275            }
5276            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5277            if (app.isolated) {
5278                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5279            }
5280            app.kill(reason, true);
5281            handleAppDiedLocked(app, true, allowRestart);
5282            removeLruProcessLocked(app);
5283
5284            if (app.persistent && !app.isolated) {
5285                if (!callerWillRestart) {
5286                    addAppLocked(app.info, false, null /* ABI override */);
5287                } else {
5288                    needRestart = true;
5289                }
5290            }
5291        } else {
5292            mRemovedProcesses.add(app);
5293        }
5294
5295        return needRestart;
5296    }
5297
5298    private final void processStartTimedOutLocked(ProcessRecord app) {
5299        final int pid = app.pid;
5300        boolean gone = false;
5301        synchronized (mPidsSelfLocked) {
5302            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5303            if (knownApp != null && knownApp.thread == null) {
5304                mPidsSelfLocked.remove(pid);
5305                gone = true;
5306            }
5307        }
5308
5309        if (gone) {
5310            Slog.w(TAG, "Process " + app + " failed to attach");
5311            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5312                    pid, app.uid, app.processName);
5313            mProcessNames.remove(app.processName, app.uid);
5314            mIsolatedProcesses.remove(app.uid);
5315            if (mHeavyWeightProcess == app) {
5316                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5317                        mHeavyWeightProcess.userId, 0));
5318                mHeavyWeightProcess = null;
5319            }
5320            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5321            if (app.isolated) {
5322                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5323            }
5324            // Take care of any launching providers waiting for this process.
5325            checkAppInLaunchingProvidersLocked(app, true);
5326            // Take care of any services that are waiting for the process.
5327            mServices.processStartTimedOutLocked(app);
5328            app.kill("start timeout", true);
5329            removeLruProcessLocked(app);
5330            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5331                Slog.w(TAG, "Unattached app died before backup, skipping");
5332                try {
5333                    IBackupManager bm = IBackupManager.Stub.asInterface(
5334                            ServiceManager.getService(Context.BACKUP_SERVICE));
5335                    bm.agentDisconnected(app.info.packageName);
5336                } catch (RemoteException e) {
5337                    // Can't happen; the backup manager is local
5338                }
5339            }
5340            if (isPendingBroadcastProcessLocked(pid)) {
5341                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5342                skipPendingBroadcastLocked(pid);
5343            }
5344        } else {
5345            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5346        }
5347    }
5348
5349    private final boolean attachApplicationLocked(IApplicationThread thread,
5350            int pid) {
5351
5352        // Find the application record that is being attached...  either via
5353        // the pid if we are running in multiple processes, or just pull the
5354        // next app record if we are emulating process with anonymous threads.
5355        ProcessRecord app;
5356        if (pid != MY_PID && pid >= 0) {
5357            synchronized (mPidsSelfLocked) {
5358                app = mPidsSelfLocked.get(pid);
5359            }
5360        } else {
5361            app = null;
5362        }
5363
5364        if (app == null) {
5365            Slog.w(TAG, "No pending application record for pid " + pid
5366                    + " (IApplicationThread " + thread + "); dropping process");
5367            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5368            if (pid > 0 && pid != MY_PID) {
5369                Process.killProcessQuiet(pid);
5370                //TODO: Process.killProcessGroup(app.info.uid, pid);
5371            } else {
5372                try {
5373                    thread.scheduleExit();
5374                } catch (Exception e) {
5375                    // Ignore exceptions.
5376                }
5377            }
5378            return false;
5379        }
5380
5381        // If this application record is still attached to a previous
5382        // process, clean it up now.
5383        if (app.thread != null) {
5384            handleAppDiedLocked(app, true, true);
5385        }
5386
5387        // Tell the process all about itself.
5388
5389        if (localLOGV) Slog.v(
5390                TAG, "Binding process pid " + pid + " to record " + app);
5391
5392        final String processName = app.processName;
5393        try {
5394            AppDeathRecipient adr = new AppDeathRecipient(
5395                    app, pid, thread);
5396            thread.asBinder().linkToDeath(adr, 0);
5397            app.deathRecipient = adr;
5398        } catch (RemoteException e) {
5399            app.resetPackageList(mProcessStats);
5400            startProcessLocked(app, "link fail", processName);
5401            return false;
5402        }
5403
5404        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5405
5406        app.makeActive(thread, mProcessStats);
5407        app.curAdj = app.setAdj = -100;
5408        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5409        app.forcingToForeground = null;
5410        updateProcessForegroundLocked(app, false, false);
5411        app.hasShownUi = false;
5412        app.debugging = false;
5413        app.cached = false;
5414        app.killedByAm = false;
5415
5416        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5417
5418        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5419        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5420
5421        if (!normalMode) {
5422            Slog.i(TAG, "Launching preboot mode app: " + app);
5423        }
5424
5425        if (localLOGV) Slog.v(
5426            TAG, "New app record " + app
5427            + " thread=" + thread.asBinder() + " pid=" + pid);
5428        try {
5429            int testMode = IApplicationThread.DEBUG_OFF;
5430            if (mDebugApp != null && mDebugApp.equals(processName)) {
5431                testMode = mWaitForDebugger
5432                    ? IApplicationThread.DEBUG_WAIT
5433                    : IApplicationThread.DEBUG_ON;
5434                app.debugging = true;
5435                if (mDebugTransient) {
5436                    mDebugApp = mOrigDebugApp;
5437                    mWaitForDebugger = mOrigWaitForDebugger;
5438                }
5439            }
5440            String profileFile = app.instrumentationProfileFile;
5441            ParcelFileDescriptor profileFd = null;
5442            int samplingInterval = 0;
5443            boolean profileAutoStop = false;
5444            if (mProfileApp != null && mProfileApp.equals(processName)) {
5445                mProfileProc = app;
5446                profileFile = mProfileFile;
5447                profileFd = mProfileFd;
5448                samplingInterval = mSamplingInterval;
5449                profileAutoStop = mAutoStopProfiler;
5450            }
5451            boolean enableOpenGlTrace = false;
5452            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
5453                enableOpenGlTrace = true;
5454                mOpenGlTraceApp = null;
5455            }
5456
5457            // If the app is being launched for restore or full backup, set it up specially
5458            boolean isRestrictedBackupMode = false;
5459            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
5460                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
5461                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
5462                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
5463            }
5464
5465            ensurePackageDexOpt(app.instrumentationInfo != null
5466                    ? app.instrumentationInfo.packageName
5467                    : app.info.packageName);
5468            if (app.instrumentationClass != null) {
5469                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
5470            }
5471            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
5472                    + processName + " with config " + mConfiguration);
5473            ApplicationInfo appInfo = app.instrumentationInfo != null
5474                    ? app.instrumentationInfo : app.info;
5475            app.compat = compatibilityInfoForPackageLocked(appInfo);
5476            if (profileFd != null) {
5477                profileFd = profileFd.dup();
5478            }
5479            ProfilerInfo profilerInfo = profileFile == null ? null
5480                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
5481            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
5482                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
5483                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
5484                    isRestrictedBackupMode || !normalMode, app.persistent,
5485                    new Configuration(mConfiguration), app.compat,
5486                    getCommonServicesLocked(app.isolated),
5487                    mCoreSettingsObserver.getCoreSettingsLocked());
5488            updateLruProcessLocked(app, false, null);
5489            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
5490        } catch (Exception e) {
5491            // todo: Yikes!  What should we do?  For now we will try to
5492            // start another process, but that could easily get us in
5493            // an infinite loop of restarting processes...
5494            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
5495
5496            app.resetPackageList(mProcessStats);
5497            app.unlinkDeathRecipient();
5498            startProcessLocked(app, "bind fail", processName);
5499            return false;
5500        }
5501
5502        // Remove this record from the list of starting applications.
5503        mPersistentStartingProcesses.remove(app);
5504        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
5505                "Attach application locked removing on hold: " + app);
5506        mProcessesOnHold.remove(app);
5507
5508        boolean badApp = false;
5509        boolean didSomething = false;
5510
5511        // See if the top visible activity is waiting to run in this process...
5512        if (normalMode) {
5513            try {
5514                if (mStackSupervisor.attachApplicationLocked(app)) {
5515                    didSomething = true;
5516                }
5517            } catch (Exception e) {
5518                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
5519                badApp = true;
5520            }
5521        }
5522
5523        // Find any services that should be running in this process...
5524        if (!badApp) {
5525            try {
5526                didSomething |= mServices.attachApplicationLocked(app, processName);
5527            } catch (Exception e) {
5528                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
5529                badApp = true;
5530            }
5531        }
5532
5533        // Check if a next-broadcast receiver is in this process...
5534        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
5535            try {
5536                didSomething |= sendPendingBroadcastsLocked(app);
5537            } catch (Exception e) {
5538                // If the app died trying to launch the receiver we declare it 'bad'
5539                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
5540                badApp = true;
5541            }
5542        }
5543
5544        // Check whether the next backup agent is in this process...
5545        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
5546            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
5547            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
5548            try {
5549                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
5550                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
5551                        mBackupTarget.backupMode);
5552            } catch (Exception e) {
5553                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
5554                badApp = true;
5555            }
5556        }
5557
5558        if (badApp) {
5559            app.kill("error during init", true);
5560            handleAppDiedLocked(app, false, true);
5561            return false;
5562        }
5563
5564        if (!didSomething) {
5565            updateOomAdjLocked();
5566        }
5567
5568        return true;
5569    }
5570
5571    @Override
5572    public final void attachApplication(IApplicationThread thread) {
5573        synchronized (this) {
5574            int callingPid = Binder.getCallingPid();
5575            final long origId = Binder.clearCallingIdentity();
5576            attachApplicationLocked(thread, callingPid);
5577            Binder.restoreCallingIdentity(origId);
5578        }
5579    }
5580
5581    @Override
5582    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
5583        final long origId = Binder.clearCallingIdentity();
5584        synchronized (this) {
5585            ActivityStack stack = ActivityRecord.getStackLocked(token);
5586            if (stack != null) {
5587                ActivityRecord r =
5588                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
5589                if (stopProfiling) {
5590                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
5591                        try {
5592                            mProfileFd.close();
5593                        } catch (IOException e) {
5594                        }
5595                        clearProfilerLocked();
5596                    }
5597                }
5598            }
5599        }
5600        Binder.restoreCallingIdentity(origId);
5601    }
5602
5603    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
5604        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
5605                finishBooting? 1 : 0, enableScreen ? 1 : 0));
5606    }
5607
5608    void enableScreenAfterBoot() {
5609        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
5610                SystemClock.uptimeMillis());
5611        mWindowManager.enableScreenAfterBoot();
5612
5613        synchronized (this) {
5614            updateEventDispatchingLocked();
5615        }
5616    }
5617
5618    @Override
5619    public void showBootMessage(final CharSequence msg, final boolean always) {
5620        enforceNotIsolatedCaller("showBootMessage");
5621        mWindowManager.showBootMessage(msg, always);
5622    }
5623
5624    @Override
5625    public void keyguardWaitingForActivityDrawn() {
5626        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
5627        final long token = Binder.clearCallingIdentity();
5628        try {
5629            synchronized (this) {
5630                if (DEBUG_LOCKSCREEN) logLockScreen("");
5631                mWindowManager.keyguardWaitingForActivityDrawn();
5632                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
5633                    mLockScreenShown = LOCK_SCREEN_LEAVING;
5634                    updateSleepIfNeededLocked();
5635                }
5636            }
5637        } finally {
5638            Binder.restoreCallingIdentity(token);
5639        }
5640    }
5641
5642    final void finishBooting() {
5643        synchronized (this) {
5644            if (!mBootAnimationComplete) {
5645                mCallFinishBooting = true;
5646                return;
5647            }
5648            mCallFinishBooting = false;
5649        }
5650
5651        ArraySet<String> completedIsas = new ArraySet<String>();
5652        for (String abi : Build.SUPPORTED_ABIS) {
5653            Process.establishZygoteConnectionForAbi(abi);
5654            final String instructionSet = VMRuntime.getInstructionSet(abi);
5655            if (!completedIsas.contains(instructionSet)) {
5656                if (mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi)) != 0) {
5657                    Slog.e(TAG, "Unable to mark boot complete for abi: " + abi);
5658                }
5659                completedIsas.add(instructionSet);
5660            }
5661        }
5662
5663        IntentFilter pkgFilter = new IntentFilter();
5664        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
5665        pkgFilter.addDataScheme("package");
5666        mContext.registerReceiver(new BroadcastReceiver() {
5667            @Override
5668            public void onReceive(Context context, Intent intent) {
5669                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
5670                if (pkgs != null) {
5671                    for (String pkg : pkgs) {
5672                        synchronized (ActivityManagerService.this) {
5673                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
5674                                    0, "finished booting")) {
5675                                setResultCode(Activity.RESULT_OK);
5676                                return;
5677                            }
5678                        }
5679                    }
5680                }
5681            }
5682        }, pkgFilter);
5683
5684        // Let system services know.
5685        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
5686
5687        synchronized (this) {
5688            // Ensure that any processes we had put on hold are now started
5689            // up.
5690            final int NP = mProcessesOnHold.size();
5691            if (NP > 0) {
5692                ArrayList<ProcessRecord> procs =
5693                    new ArrayList<ProcessRecord>(mProcessesOnHold);
5694                for (int ip=0; ip<NP; ip++) {
5695                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
5696                            + procs.get(ip));
5697                    startProcessLocked(procs.get(ip), "on-hold", null);
5698                }
5699            }
5700
5701            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
5702                // Start looking for apps that are abusing wake locks.
5703                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
5704                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
5705                // Tell anyone interested that we are done booting!
5706                SystemProperties.set("sys.boot_completed", "1");
5707
5708                // And trigger dev.bootcomplete if we are not showing encryption progress
5709                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
5710                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
5711                    SystemProperties.set("dev.bootcomplete", "1");
5712                }
5713                for (int i=0; i<mStartedUsers.size(); i++) {
5714                    UserStartedState uss = mStartedUsers.valueAt(i);
5715                    if (uss.mState == UserStartedState.STATE_BOOTING) {
5716                        uss.mState = UserStartedState.STATE_RUNNING;
5717                        final int userId = mStartedUsers.keyAt(i);
5718                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
5719                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5720                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
5721                        broadcastIntentLocked(null, null, intent, null,
5722                                new IIntentReceiver.Stub() {
5723                                    @Override
5724                                    public void performReceive(Intent intent, int resultCode,
5725                                            String data, Bundle extras, boolean ordered,
5726                                            boolean sticky, int sendingUser) {
5727                                        synchronized (ActivityManagerService.this) {
5728                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
5729                                                    true, false);
5730                                        }
5731                                    }
5732                                },
5733                                0, null, null,
5734                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
5735                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
5736                                userId);
5737                    }
5738                }
5739                scheduleStartProfilesLocked();
5740            }
5741        }
5742    }
5743
5744    @Override
5745    public void bootAnimationComplete() {
5746        final boolean callFinishBooting;
5747        synchronized (this) {
5748            callFinishBooting = mCallFinishBooting;
5749            mBootAnimationComplete = true;
5750        }
5751        if (callFinishBooting) {
5752            finishBooting();
5753        }
5754    }
5755
5756    @Override
5757    public void systemBackupRestored() {
5758        synchronized (this) {
5759            if (mSystemReady) {
5760                mTaskPersister.restoreTasksFromOtherDeviceLocked();
5761            } else {
5762                Slog.w(TAG, "System backup restored before system is ready");
5763            }
5764        }
5765    }
5766
5767    final void ensureBootCompleted() {
5768        boolean booting;
5769        boolean enableScreen;
5770        synchronized (this) {
5771            booting = mBooting;
5772            mBooting = false;
5773            enableScreen = !mBooted;
5774            mBooted = true;
5775        }
5776
5777        if (booting) {
5778            finishBooting();
5779        }
5780
5781        if (enableScreen) {
5782            enableScreenAfterBoot();
5783        }
5784    }
5785
5786    @Override
5787    public final void activityResumed(IBinder token) {
5788        final long origId = Binder.clearCallingIdentity();
5789        synchronized(this) {
5790            ActivityStack stack = ActivityRecord.getStackLocked(token);
5791            if (stack != null) {
5792                ActivityRecord.activityResumedLocked(token);
5793            }
5794        }
5795        Binder.restoreCallingIdentity(origId);
5796    }
5797
5798    @Override
5799    public final void activityPaused(IBinder token) {
5800        final long origId = Binder.clearCallingIdentity();
5801        synchronized(this) {
5802            ActivityStack stack = ActivityRecord.getStackLocked(token);
5803            if (stack != null) {
5804                stack.activityPausedLocked(token, false);
5805            }
5806        }
5807        Binder.restoreCallingIdentity(origId);
5808    }
5809
5810    @Override
5811    public final void activityStopped(IBinder token, Bundle icicle,
5812            PersistableBundle persistentState, CharSequence description) {
5813        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
5814
5815        // Refuse possible leaked file descriptors
5816        if (icicle != null && icicle.hasFileDescriptors()) {
5817            throw new IllegalArgumentException("File descriptors passed in Bundle");
5818        }
5819
5820        final long origId = Binder.clearCallingIdentity();
5821
5822        synchronized (this) {
5823            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5824            if (r != null) {
5825                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
5826            }
5827        }
5828
5829        trimApplications();
5830
5831        Binder.restoreCallingIdentity(origId);
5832    }
5833
5834    @Override
5835    public final void activityDestroyed(IBinder token) {
5836        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
5837        synchronized (this) {
5838            ActivityStack stack = ActivityRecord.getStackLocked(token);
5839            if (stack != null) {
5840                stack.activityDestroyedLocked(token);
5841            }
5842        }
5843    }
5844
5845    @Override
5846    public final void backgroundResourcesReleased(IBinder token) {
5847        final long origId = Binder.clearCallingIdentity();
5848        try {
5849            synchronized (this) {
5850                ActivityStack stack = ActivityRecord.getStackLocked(token);
5851                if (stack != null) {
5852                    stack.backgroundResourcesReleased();
5853                }
5854            }
5855        } finally {
5856            Binder.restoreCallingIdentity(origId);
5857        }
5858    }
5859
5860    @Override
5861    public final void notifyLaunchTaskBehindComplete(IBinder token) {
5862        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
5863    }
5864
5865    @Override
5866    public final void notifyEnterAnimationComplete(IBinder token) {
5867        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
5868    }
5869
5870    @Override
5871    public String getCallingPackage(IBinder token) {
5872        synchronized (this) {
5873            ActivityRecord r = getCallingRecordLocked(token);
5874            return r != null ? r.info.packageName : null;
5875        }
5876    }
5877
5878    @Override
5879    public ComponentName getCallingActivity(IBinder token) {
5880        synchronized (this) {
5881            ActivityRecord r = getCallingRecordLocked(token);
5882            return r != null ? r.intent.getComponent() : null;
5883        }
5884    }
5885
5886    private ActivityRecord getCallingRecordLocked(IBinder token) {
5887        ActivityRecord r = ActivityRecord.isInStackLocked(token);
5888        if (r == null) {
5889            return null;
5890        }
5891        return r.resultTo;
5892    }
5893
5894    @Override
5895    public ComponentName getActivityClassForToken(IBinder token) {
5896        synchronized(this) {
5897            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5898            if (r == null) {
5899                return null;
5900            }
5901            return r.intent.getComponent();
5902        }
5903    }
5904
5905    @Override
5906    public String getPackageForToken(IBinder token) {
5907        synchronized(this) {
5908            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5909            if (r == null) {
5910                return null;
5911            }
5912            return r.packageName;
5913        }
5914    }
5915
5916    @Override
5917    public IIntentSender getIntentSender(int type,
5918            String packageName, IBinder token, String resultWho,
5919            int requestCode, Intent[] intents, String[] resolvedTypes,
5920            int flags, Bundle options, int userId) {
5921        enforceNotIsolatedCaller("getIntentSender");
5922        // Refuse possible leaked file descriptors
5923        if (intents != null) {
5924            if (intents.length < 1) {
5925                throw new IllegalArgumentException("Intents array length must be >= 1");
5926            }
5927            for (int i=0; i<intents.length; i++) {
5928                Intent intent = intents[i];
5929                if (intent != null) {
5930                    if (intent.hasFileDescriptors()) {
5931                        throw new IllegalArgumentException("File descriptors passed in Intent");
5932                    }
5933                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
5934                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
5935                        throw new IllegalArgumentException(
5936                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
5937                    }
5938                    intents[i] = new Intent(intent);
5939                }
5940            }
5941            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
5942                throw new IllegalArgumentException(
5943                        "Intent array length does not match resolvedTypes length");
5944            }
5945        }
5946        if (options != null) {
5947            if (options.hasFileDescriptors()) {
5948                throw new IllegalArgumentException("File descriptors passed in options");
5949            }
5950        }
5951
5952        synchronized(this) {
5953            int callingUid = Binder.getCallingUid();
5954            int origUserId = userId;
5955            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
5956                    type == ActivityManager.INTENT_SENDER_BROADCAST,
5957                    ALLOW_NON_FULL, "getIntentSender", null);
5958            if (origUserId == UserHandle.USER_CURRENT) {
5959                // We don't want to evaluate this until the pending intent is
5960                // actually executed.  However, we do want to always do the
5961                // security checking for it above.
5962                userId = UserHandle.USER_CURRENT;
5963            }
5964            try {
5965                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
5966                    int uid = AppGlobals.getPackageManager()
5967                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
5968                    if (!UserHandle.isSameApp(callingUid, uid)) {
5969                        String msg = "Permission Denial: getIntentSender() from pid="
5970                            + Binder.getCallingPid()
5971                            + ", uid=" + Binder.getCallingUid()
5972                            + ", (need uid=" + uid + ")"
5973                            + " is not allowed to send as package " + packageName;
5974                        Slog.w(TAG, msg);
5975                        throw new SecurityException(msg);
5976                    }
5977                }
5978
5979                return getIntentSenderLocked(type, packageName, callingUid, userId,
5980                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
5981
5982            } catch (RemoteException e) {
5983                throw new SecurityException(e);
5984            }
5985        }
5986    }
5987
5988    IIntentSender getIntentSenderLocked(int type, String packageName,
5989            int callingUid, int userId, IBinder token, String resultWho,
5990            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
5991            Bundle options) {
5992        if (DEBUG_MU)
5993            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
5994        ActivityRecord activity = null;
5995        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5996            activity = ActivityRecord.isInStackLocked(token);
5997            if (activity == null) {
5998                return null;
5999            }
6000            if (activity.finishing) {
6001                return null;
6002            }
6003        }
6004
6005        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6006        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6007        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6008        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6009                |PendingIntent.FLAG_UPDATE_CURRENT);
6010
6011        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6012                type, packageName, activity, resultWho,
6013                requestCode, intents, resolvedTypes, flags, options, userId);
6014        WeakReference<PendingIntentRecord> ref;
6015        ref = mIntentSenderRecords.get(key);
6016        PendingIntentRecord rec = ref != null ? ref.get() : null;
6017        if (rec != null) {
6018            if (!cancelCurrent) {
6019                if (updateCurrent) {
6020                    if (rec.key.requestIntent != null) {
6021                        rec.key.requestIntent.replaceExtras(intents != null ?
6022                                intents[intents.length - 1] : null);
6023                    }
6024                    if (intents != null) {
6025                        intents[intents.length-1] = rec.key.requestIntent;
6026                        rec.key.allIntents = intents;
6027                        rec.key.allResolvedTypes = resolvedTypes;
6028                    } else {
6029                        rec.key.allIntents = null;
6030                        rec.key.allResolvedTypes = null;
6031                    }
6032                }
6033                return rec;
6034            }
6035            rec.canceled = true;
6036            mIntentSenderRecords.remove(key);
6037        }
6038        if (noCreate) {
6039            return rec;
6040        }
6041        rec = new PendingIntentRecord(this, key, callingUid);
6042        mIntentSenderRecords.put(key, rec.ref);
6043        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6044            if (activity.pendingResults == null) {
6045                activity.pendingResults
6046                        = new HashSet<WeakReference<PendingIntentRecord>>();
6047            }
6048            activity.pendingResults.add(rec.ref);
6049        }
6050        return rec;
6051    }
6052
6053    @Override
6054    public void cancelIntentSender(IIntentSender sender) {
6055        if (!(sender instanceof PendingIntentRecord)) {
6056            return;
6057        }
6058        synchronized(this) {
6059            PendingIntentRecord rec = (PendingIntentRecord)sender;
6060            try {
6061                int uid = AppGlobals.getPackageManager()
6062                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
6063                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6064                    String msg = "Permission Denial: cancelIntentSender() from pid="
6065                        + Binder.getCallingPid()
6066                        + ", uid=" + Binder.getCallingUid()
6067                        + " is not allowed to cancel packges "
6068                        + rec.key.packageName;
6069                    Slog.w(TAG, msg);
6070                    throw new SecurityException(msg);
6071                }
6072            } catch (RemoteException e) {
6073                throw new SecurityException(e);
6074            }
6075            cancelIntentSenderLocked(rec, true);
6076        }
6077    }
6078
6079    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
6080        rec.canceled = true;
6081        mIntentSenderRecords.remove(rec.key);
6082        if (cleanActivity && rec.key.activity != null) {
6083            rec.key.activity.pendingResults.remove(rec.ref);
6084        }
6085    }
6086
6087    @Override
6088    public String getPackageForIntentSender(IIntentSender pendingResult) {
6089        if (!(pendingResult instanceof PendingIntentRecord)) {
6090            return null;
6091        }
6092        try {
6093            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6094            return res.key.packageName;
6095        } catch (ClassCastException e) {
6096        }
6097        return null;
6098    }
6099
6100    @Override
6101    public int getUidForIntentSender(IIntentSender sender) {
6102        if (sender instanceof PendingIntentRecord) {
6103            try {
6104                PendingIntentRecord res = (PendingIntentRecord)sender;
6105                return res.uid;
6106            } catch (ClassCastException e) {
6107            }
6108        }
6109        return -1;
6110    }
6111
6112    @Override
6113    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
6114        if (!(pendingResult instanceof PendingIntentRecord)) {
6115            return false;
6116        }
6117        try {
6118            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6119            if (res.key.allIntents == null) {
6120                return false;
6121            }
6122            for (int i=0; i<res.key.allIntents.length; i++) {
6123                Intent intent = res.key.allIntents[i];
6124                if (intent.getPackage() != null && intent.getComponent() != null) {
6125                    return false;
6126                }
6127            }
6128            return true;
6129        } catch (ClassCastException e) {
6130        }
6131        return false;
6132    }
6133
6134    @Override
6135    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
6136        if (!(pendingResult instanceof PendingIntentRecord)) {
6137            return false;
6138        }
6139        try {
6140            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6141            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6142                return true;
6143            }
6144            return false;
6145        } catch (ClassCastException e) {
6146        }
6147        return false;
6148    }
6149
6150    @Override
6151    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6152        if (!(pendingResult instanceof PendingIntentRecord)) {
6153            return null;
6154        }
6155        try {
6156            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6157            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6158        } catch (ClassCastException e) {
6159        }
6160        return null;
6161    }
6162
6163    @Override
6164    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6165        if (!(pendingResult instanceof PendingIntentRecord)) {
6166            return null;
6167        }
6168        try {
6169            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6170            Intent intent = res.key.requestIntent;
6171            if (intent != null) {
6172                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6173                        || res.lastTagPrefix.equals(prefix))) {
6174                    return res.lastTag;
6175                }
6176                res.lastTagPrefix = prefix;
6177                StringBuilder sb = new StringBuilder(128);
6178                if (prefix != null) {
6179                    sb.append(prefix);
6180                }
6181                if (intent.getAction() != null) {
6182                    sb.append(intent.getAction());
6183                } else if (intent.getComponent() != null) {
6184                    intent.getComponent().appendShortString(sb);
6185                } else {
6186                    sb.append("?");
6187                }
6188                return res.lastTag = sb.toString();
6189            }
6190        } catch (ClassCastException e) {
6191        }
6192        return null;
6193    }
6194
6195    @Override
6196    public void setProcessLimit(int max) {
6197        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6198                "setProcessLimit()");
6199        synchronized (this) {
6200            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6201            mProcessLimitOverride = max;
6202        }
6203        trimApplications();
6204    }
6205
6206    @Override
6207    public int getProcessLimit() {
6208        synchronized (this) {
6209            return mProcessLimitOverride;
6210        }
6211    }
6212
6213    void foregroundTokenDied(ForegroundToken token) {
6214        synchronized (ActivityManagerService.this) {
6215            synchronized (mPidsSelfLocked) {
6216                ForegroundToken cur
6217                    = mForegroundProcesses.get(token.pid);
6218                if (cur != token) {
6219                    return;
6220                }
6221                mForegroundProcesses.remove(token.pid);
6222                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6223                if (pr == null) {
6224                    return;
6225                }
6226                pr.forcingToForeground = null;
6227                updateProcessForegroundLocked(pr, false, false);
6228            }
6229            updateOomAdjLocked();
6230        }
6231    }
6232
6233    @Override
6234    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6235        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6236                "setProcessForeground()");
6237        synchronized(this) {
6238            boolean changed = false;
6239
6240            synchronized (mPidsSelfLocked) {
6241                ProcessRecord pr = mPidsSelfLocked.get(pid);
6242                if (pr == null && isForeground) {
6243                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6244                    return;
6245                }
6246                ForegroundToken oldToken = mForegroundProcesses.get(pid);
6247                if (oldToken != null) {
6248                    oldToken.token.unlinkToDeath(oldToken, 0);
6249                    mForegroundProcesses.remove(pid);
6250                    if (pr != null) {
6251                        pr.forcingToForeground = null;
6252                    }
6253                    changed = true;
6254                }
6255                if (isForeground && token != null) {
6256                    ForegroundToken newToken = new ForegroundToken() {
6257                        @Override
6258                        public void binderDied() {
6259                            foregroundTokenDied(this);
6260                        }
6261                    };
6262                    newToken.pid = pid;
6263                    newToken.token = token;
6264                    try {
6265                        token.linkToDeath(newToken, 0);
6266                        mForegroundProcesses.put(pid, newToken);
6267                        pr.forcingToForeground = token;
6268                        changed = true;
6269                    } catch (RemoteException e) {
6270                        // If the process died while doing this, we will later
6271                        // do the cleanup with the process death link.
6272                    }
6273                }
6274            }
6275
6276            if (changed) {
6277                updateOomAdjLocked();
6278            }
6279        }
6280    }
6281
6282    // =========================================================
6283    // PERMISSIONS
6284    // =========================================================
6285
6286    static class PermissionController extends IPermissionController.Stub {
6287        ActivityManagerService mActivityManagerService;
6288        PermissionController(ActivityManagerService activityManagerService) {
6289            mActivityManagerService = activityManagerService;
6290        }
6291
6292        @Override
6293        public boolean checkPermission(String permission, int pid, int uid) {
6294            return mActivityManagerService.checkPermission(permission, pid,
6295                    uid) == PackageManager.PERMISSION_GRANTED;
6296        }
6297    }
6298
6299    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6300        @Override
6301        public int checkComponentPermission(String permission, int pid, int uid,
6302                int owningUid, boolean exported) {
6303            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6304                    owningUid, exported);
6305        }
6306
6307        @Override
6308        public Object getAMSLock() {
6309            return ActivityManagerService.this;
6310        }
6311    }
6312
6313    /**
6314     * This can be called with or without the global lock held.
6315     */
6316    int checkComponentPermission(String permission, int pid, int uid,
6317            int owningUid, boolean exported) {
6318        if (pid == MY_PID) {
6319            return PackageManager.PERMISSION_GRANTED;
6320        }
6321        return ActivityManager.checkComponentPermission(permission, uid,
6322                owningUid, exported);
6323    }
6324
6325    /**
6326     * As the only public entry point for permissions checking, this method
6327     * can enforce the semantic that requesting a check on a null global
6328     * permission is automatically denied.  (Internally a null permission
6329     * string is used when calling {@link #checkComponentPermission} in cases
6330     * when only uid-based security is needed.)
6331     *
6332     * This can be called with or without the global lock held.
6333     */
6334    @Override
6335    public int checkPermission(String permission, int pid, int uid) {
6336        if (permission == null) {
6337            return PackageManager.PERMISSION_DENIED;
6338        }
6339        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6340    }
6341
6342    @Override
6343    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
6344        if (permission == null) {
6345            return PackageManager.PERMISSION_DENIED;
6346        }
6347
6348        // We might be performing an operation on behalf of an indirect binder
6349        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
6350        // client identity accordingly before proceeding.
6351        Identity tlsIdentity = sCallerIdentity.get();
6352        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
6353            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6354                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6355            uid = tlsIdentity.uid;
6356            pid = tlsIdentity.pid;
6357        }
6358
6359        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6360    }
6361
6362    /**
6363     * Binder IPC calls go through the public entry point.
6364     * This can be called with or without the global lock held.
6365     */
6366    int checkCallingPermission(String permission) {
6367        return checkPermission(permission,
6368                Binder.getCallingPid(),
6369                UserHandle.getAppId(Binder.getCallingUid()));
6370    }
6371
6372    /**
6373     * This can be called with or without the global lock held.
6374     */
6375    void enforceCallingPermission(String permission, String func) {
6376        if (checkCallingPermission(permission)
6377                == PackageManager.PERMISSION_GRANTED) {
6378            return;
6379        }
6380
6381        String msg = "Permission Denial: " + func + " from pid="
6382                + Binder.getCallingPid()
6383                + ", uid=" + Binder.getCallingUid()
6384                + " requires " + permission;
6385        Slog.w(TAG, msg);
6386        throw new SecurityException(msg);
6387    }
6388
6389    /**
6390     * Determine if UID is holding permissions required to access {@link Uri} in
6391     * the given {@link ProviderInfo}. Final permission checking is always done
6392     * in {@link ContentProvider}.
6393     */
6394    private final boolean checkHoldingPermissionsLocked(
6395            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
6396        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6397                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
6398        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
6399            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
6400                    != PERMISSION_GRANTED) {
6401                return false;
6402            }
6403        }
6404        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
6405    }
6406
6407    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
6408            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
6409        if (pi.applicationInfo.uid == uid) {
6410            return true;
6411        } else if (!pi.exported) {
6412            return false;
6413        }
6414
6415        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6416        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6417        try {
6418            // check if target holds top-level <provider> permissions
6419            if (!readMet && pi.readPermission != null && considerUidPermissions
6420                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6421                readMet = true;
6422            }
6423            if (!writeMet && pi.writePermission != null && considerUidPermissions
6424                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6425                writeMet = true;
6426            }
6427
6428            // track if unprotected read/write is allowed; any denied
6429            // <path-permission> below removes this ability
6430            boolean allowDefaultRead = pi.readPermission == null;
6431            boolean allowDefaultWrite = pi.writePermission == null;
6432
6433            // check if target holds any <path-permission> that match uri
6434            final PathPermission[] pps = pi.pathPermissions;
6435            if (pps != null) {
6436                final String path = grantUri.uri.getPath();
6437                int i = pps.length;
6438                while (i > 0 && (!readMet || !writeMet)) {
6439                    i--;
6440                    PathPermission pp = pps[i];
6441                    if (pp.match(path)) {
6442                        if (!readMet) {
6443                            final String pprperm = pp.getReadPermission();
6444                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
6445                                    + pprperm + " for " + pp.getPath()
6446                                    + ": match=" + pp.match(path)
6447                                    + " check=" + pm.checkUidPermission(pprperm, uid));
6448                            if (pprperm != null) {
6449                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
6450                                        == PERMISSION_GRANTED) {
6451                                    readMet = true;
6452                                } else {
6453                                    allowDefaultRead = false;
6454                                }
6455                            }
6456                        }
6457                        if (!writeMet) {
6458                            final String ppwperm = pp.getWritePermission();
6459                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
6460                                    + ppwperm + " for " + pp.getPath()
6461                                    + ": match=" + pp.match(path)
6462                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
6463                            if (ppwperm != null) {
6464                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
6465                                        == PERMISSION_GRANTED) {
6466                                    writeMet = true;
6467                                } else {
6468                                    allowDefaultWrite = false;
6469                                }
6470                            }
6471                        }
6472                    }
6473                }
6474            }
6475
6476            // grant unprotected <provider> read/write, if not blocked by
6477            // <path-permission> above
6478            if (allowDefaultRead) readMet = true;
6479            if (allowDefaultWrite) writeMet = true;
6480
6481        } catch (RemoteException e) {
6482            return false;
6483        }
6484
6485        return readMet && writeMet;
6486    }
6487
6488    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
6489        ProviderInfo pi = null;
6490        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
6491        if (cpr != null) {
6492            pi = cpr.info;
6493        } else {
6494            try {
6495                pi = AppGlobals.getPackageManager().resolveContentProvider(
6496                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
6497            } catch (RemoteException ex) {
6498            }
6499        }
6500        return pi;
6501    }
6502
6503    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
6504        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6505        if (targetUris != null) {
6506            return targetUris.get(grantUri);
6507        }
6508        return null;
6509    }
6510
6511    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
6512            String targetPkg, int targetUid, GrantUri grantUri) {
6513        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6514        if (targetUris == null) {
6515            targetUris = Maps.newArrayMap();
6516            mGrantedUriPermissions.put(targetUid, targetUris);
6517        }
6518
6519        UriPermission perm = targetUris.get(grantUri);
6520        if (perm == null) {
6521            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
6522            targetUris.put(grantUri, perm);
6523        }
6524
6525        return perm;
6526    }
6527
6528    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
6529            final int modeFlags) {
6530        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
6531        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
6532                : UriPermission.STRENGTH_OWNED;
6533
6534        // Root gets to do everything.
6535        if (uid == 0) {
6536            return true;
6537        }
6538
6539        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6540        if (perms == null) return false;
6541
6542        // First look for exact match
6543        final UriPermission exactPerm = perms.get(grantUri);
6544        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
6545            return true;
6546        }
6547
6548        // No exact match, look for prefixes
6549        final int N = perms.size();
6550        for (int i = 0; i < N; i++) {
6551            final UriPermission perm = perms.valueAt(i);
6552            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
6553                    && perm.getStrength(modeFlags) >= minStrength) {
6554                return true;
6555            }
6556        }
6557
6558        return false;
6559    }
6560
6561    /**
6562     * @param uri This uri must NOT contain an embedded userId.
6563     * @param userId The userId in which the uri is to be resolved.
6564     */
6565    @Override
6566    public int checkUriPermission(Uri uri, int pid, int uid,
6567            final int modeFlags, int userId, IBinder callerToken) {
6568        enforceNotIsolatedCaller("checkUriPermission");
6569
6570        // Another redirected-binder-call permissions check as in
6571        // {@link checkPermissionWithToken}.
6572        Identity tlsIdentity = sCallerIdentity.get();
6573        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
6574            uid = tlsIdentity.uid;
6575            pid = tlsIdentity.pid;
6576        }
6577
6578        // Our own process gets to do everything.
6579        if (pid == MY_PID) {
6580            return PackageManager.PERMISSION_GRANTED;
6581        }
6582        synchronized (this) {
6583            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
6584                    ? PackageManager.PERMISSION_GRANTED
6585                    : PackageManager.PERMISSION_DENIED;
6586        }
6587    }
6588
6589    /**
6590     * Check if the targetPkg can be granted permission to access uri by
6591     * the callingUid using the given modeFlags.  Throws a security exception
6592     * if callingUid is not allowed to do this.  Returns the uid of the target
6593     * if the URI permission grant should be performed; returns -1 if it is not
6594     * needed (for example targetPkg already has permission to access the URI).
6595     * If you already know the uid of the target, you can supply it in
6596     * lastTargetUid else set that to -1.
6597     */
6598    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6599            final int modeFlags, int lastTargetUid) {
6600        if (!Intent.isAccessUriMode(modeFlags)) {
6601            return -1;
6602        }
6603
6604        if (targetPkg != null) {
6605            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6606                    "Checking grant " + targetPkg + " permission to " + grantUri);
6607        }
6608
6609        final IPackageManager pm = AppGlobals.getPackageManager();
6610
6611        // If this is not a content: uri, we can't do anything with it.
6612        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
6613            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6614                    "Can't grant URI permission for non-content URI: " + grantUri);
6615            return -1;
6616        }
6617
6618        final String authority = grantUri.uri.getAuthority();
6619        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6620        if (pi == null) {
6621            Slog.w(TAG, "No content provider found for permission check: " +
6622                    grantUri.uri.toSafeString());
6623            return -1;
6624        }
6625
6626        int targetUid = lastTargetUid;
6627        if (targetUid < 0 && targetPkg != null) {
6628            try {
6629                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
6630                if (targetUid < 0) {
6631                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6632                            "Can't grant URI permission no uid for: " + targetPkg);
6633                    return -1;
6634                }
6635            } catch (RemoteException ex) {
6636                return -1;
6637            }
6638        }
6639
6640        if (targetUid >= 0) {
6641            // First...  does the target actually need this permission?
6642            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
6643                // No need to grant the target this permission.
6644                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6645                        "Target " + targetPkg + " already has full permission to " + grantUri);
6646                return -1;
6647            }
6648        } else {
6649            // First...  there is no target package, so can anyone access it?
6650            boolean allowed = pi.exported;
6651            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
6652                if (pi.readPermission != null) {
6653                    allowed = false;
6654                }
6655            }
6656            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
6657                if (pi.writePermission != null) {
6658                    allowed = false;
6659                }
6660            }
6661            if (allowed) {
6662                return -1;
6663            }
6664        }
6665
6666        /* There is a special cross user grant if:
6667         * - The target is on another user.
6668         * - Apps on the current user can access the uri without any uid permissions.
6669         * In this case, we grant a uri permission, even if the ContentProvider does not normally
6670         * grant uri permissions.
6671         */
6672        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
6673                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
6674                modeFlags, false /*without considering the uid permissions*/);
6675
6676        // Second...  is the provider allowing granting of URI permissions?
6677        if (!specialCrossUserGrant) {
6678            if (!pi.grantUriPermissions) {
6679                throw new SecurityException("Provider " + pi.packageName
6680                        + "/" + pi.name
6681                        + " does not allow granting of Uri permissions (uri "
6682                        + grantUri + ")");
6683            }
6684            if (pi.uriPermissionPatterns != null) {
6685                final int N = pi.uriPermissionPatterns.length;
6686                boolean allowed = false;
6687                for (int i=0; i<N; i++) {
6688                    if (pi.uriPermissionPatterns[i] != null
6689                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
6690                        allowed = true;
6691                        break;
6692                    }
6693                }
6694                if (!allowed) {
6695                    throw new SecurityException("Provider " + pi.packageName
6696                            + "/" + pi.name
6697                            + " does not allow granting of permission to path of Uri "
6698                            + grantUri);
6699                }
6700            }
6701        }
6702
6703        // Third...  does the caller itself have permission to access
6704        // this uri?
6705        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
6706            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
6707                // Require they hold a strong enough Uri permission
6708                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
6709                    throw new SecurityException("Uid " + callingUid
6710                            + " does not have permission to uri " + grantUri);
6711                }
6712            }
6713        }
6714        return targetUid;
6715    }
6716
6717    /**
6718     * @param uri This uri must NOT contain an embedded userId.
6719     * @param userId The userId in which the uri is to be resolved.
6720     */
6721    @Override
6722    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
6723            final int modeFlags, int userId) {
6724        enforceNotIsolatedCaller("checkGrantUriPermission");
6725        synchronized(this) {
6726            return checkGrantUriPermissionLocked(callingUid, targetPkg,
6727                    new GrantUri(userId, uri, false), modeFlags, -1);
6728        }
6729    }
6730
6731    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
6732            final int modeFlags, UriPermissionOwner owner) {
6733        if (!Intent.isAccessUriMode(modeFlags)) {
6734            return;
6735        }
6736
6737        // So here we are: the caller has the assumed permission
6738        // to the uri, and the target doesn't.  Let's now give this to
6739        // the target.
6740
6741        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6742                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
6743
6744        final String authority = grantUri.uri.getAuthority();
6745        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6746        if (pi == null) {
6747            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
6748            return;
6749        }
6750
6751        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
6752            grantUri.prefix = true;
6753        }
6754        final UriPermission perm = findOrCreateUriPermissionLocked(
6755                pi.packageName, targetPkg, targetUid, grantUri);
6756        perm.grantModes(modeFlags, owner);
6757    }
6758
6759    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6760            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
6761        if (targetPkg == null) {
6762            throw new NullPointerException("targetPkg");
6763        }
6764        int targetUid;
6765        final IPackageManager pm = AppGlobals.getPackageManager();
6766        try {
6767            targetUid = pm.getPackageUid(targetPkg, targetUserId);
6768        } catch (RemoteException ex) {
6769            return;
6770        }
6771
6772        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
6773                targetUid);
6774        if (targetUid < 0) {
6775            return;
6776        }
6777
6778        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
6779                owner);
6780    }
6781
6782    static class NeededUriGrants extends ArrayList<GrantUri> {
6783        final String targetPkg;
6784        final int targetUid;
6785        final int flags;
6786
6787        NeededUriGrants(String targetPkg, int targetUid, int flags) {
6788            this.targetPkg = targetPkg;
6789            this.targetUid = targetUid;
6790            this.flags = flags;
6791        }
6792    }
6793
6794    /**
6795     * Like checkGrantUriPermissionLocked, but takes an Intent.
6796     */
6797    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
6798            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
6799        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6800                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
6801                + " clip=" + (intent != null ? intent.getClipData() : null)
6802                + " from " + intent + "; flags=0x"
6803                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
6804
6805        if (targetPkg == null) {
6806            throw new NullPointerException("targetPkg");
6807        }
6808
6809        if (intent == null) {
6810            return null;
6811        }
6812        Uri data = intent.getData();
6813        ClipData clip = intent.getClipData();
6814        if (data == null && clip == null) {
6815            return null;
6816        }
6817        // Default userId for uris in the intent (if they don't specify it themselves)
6818        int contentUserHint = intent.getContentUserHint();
6819        if (contentUserHint == UserHandle.USER_CURRENT) {
6820            contentUserHint = UserHandle.getUserId(callingUid);
6821        }
6822        final IPackageManager pm = AppGlobals.getPackageManager();
6823        int targetUid;
6824        if (needed != null) {
6825            targetUid = needed.targetUid;
6826        } else {
6827            try {
6828                targetUid = pm.getPackageUid(targetPkg, targetUserId);
6829            } catch (RemoteException ex) {
6830                return null;
6831            }
6832            if (targetUid < 0) {
6833                if (DEBUG_URI_PERMISSION) {
6834                    Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
6835                            + " on user " + targetUserId);
6836                }
6837                return null;
6838            }
6839        }
6840        if (data != null) {
6841            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
6842            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
6843                    targetUid);
6844            if (targetUid > 0) {
6845                if (needed == null) {
6846                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
6847                }
6848                needed.add(grantUri);
6849            }
6850        }
6851        if (clip != null) {
6852            for (int i=0; i<clip.getItemCount(); i++) {
6853                Uri uri = clip.getItemAt(i).getUri();
6854                if (uri != null) {
6855                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
6856                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
6857                            targetUid);
6858                    if (targetUid > 0) {
6859                        if (needed == null) {
6860                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
6861                        }
6862                        needed.add(grantUri);
6863                    }
6864                } else {
6865                    Intent clipIntent = clip.getItemAt(i).getIntent();
6866                    if (clipIntent != null) {
6867                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
6868                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
6869                        if (newNeeded != null) {
6870                            needed = newNeeded;
6871                        }
6872                    }
6873                }
6874            }
6875        }
6876
6877        return needed;
6878    }
6879
6880    /**
6881     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
6882     */
6883    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
6884            UriPermissionOwner owner) {
6885        if (needed != null) {
6886            for (int i=0; i<needed.size(); i++) {
6887                GrantUri grantUri = needed.get(i);
6888                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
6889                        grantUri, needed.flags, owner);
6890            }
6891        }
6892    }
6893
6894    void grantUriPermissionFromIntentLocked(int callingUid,
6895            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
6896        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
6897                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
6898        if (needed == null) {
6899            return;
6900        }
6901
6902        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
6903    }
6904
6905    /**
6906     * @param uri This uri must NOT contain an embedded userId.
6907     * @param userId The userId in which the uri is to be resolved.
6908     */
6909    @Override
6910    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
6911            final int modeFlags, int userId) {
6912        enforceNotIsolatedCaller("grantUriPermission");
6913        GrantUri grantUri = new GrantUri(userId, uri, false);
6914        synchronized(this) {
6915            final ProcessRecord r = getRecordForAppLocked(caller);
6916            if (r == null) {
6917                throw new SecurityException("Unable to find app for caller "
6918                        + caller
6919                        + " when granting permission to uri " + grantUri);
6920            }
6921            if (targetPkg == null) {
6922                throw new IllegalArgumentException("null target");
6923            }
6924            if (grantUri == null) {
6925                throw new IllegalArgumentException("null uri");
6926            }
6927
6928            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
6929                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
6930                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
6931                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
6932
6933            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
6934                    UserHandle.getUserId(r.uid));
6935        }
6936    }
6937
6938    void removeUriPermissionIfNeededLocked(UriPermission perm) {
6939        if (perm.modeFlags == 0) {
6940            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
6941                    perm.targetUid);
6942            if (perms != null) {
6943                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6944                        "Removing " + perm.targetUid + " permission to " + perm.uri);
6945
6946                perms.remove(perm.uri);
6947                if (perms.isEmpty()) {
6948                    mGrantedUriPermissions.remove(perm.targetUid);
6949                }
6950            }
6951        }
6952    }
6953
6954    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
6955        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
6956
6957        final IPackageManager pm = AppGlobals.getPackageManager();
6958        final String authority = grantUri.uri.getAuthority();
6959        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6960        if (pi == null) {
6961            Slog.w(TAG, "No content provider found for permission revoke: "
6962                    + grantUri.toSafeString());
6963            return;
6964        }
6965
6966        // Does the caller have this permission on the URI?
6967        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
6968            // If they don't have direct access to the URI, then revoke any
6969            // ownerless URI permissions that have been granted to them.
6970            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
6971            if (perms != null) {
6972                boolean persistChanged = false;
6973                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6974                    final UriPermission perm = it.next();
6975                    if (perm.uri.sourceUserId == grantUri.sourceUserId
6976                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
6977                        if (DEBUG_URI_PERMISSION)
6978                            Slog.v(TAG, "Revoking non-owned " + perm.targetUid +
6979                                    " permission to " + perm.uri);
6980                        persistChanged |= perm.revokeModes(
6981                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
6982                        if (perm.modeFlags == 0) {
6983                            it.remove();
6984                        }
6985                    }
6986                }
6987                if (perms.isEmpty()) {
6988                    mGrantedUriPermissions.remove(callingUid);
6989                }
6990                if (persistChanged) {
6991                    schedulePersistUriGrants();
6992                }
6993            }
6994            return;
6995        }
6996
6997        boolean persistChanged = false;
6998
6999        // Go through all of the permissions and remove any that match.
7000        int N = mGrantedUriPermissions.size();
7001        for (int i = 0; i < N; i++) {
7002            final int targetUid = mGrantedUriPermissions.keyAt(i);
7003            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7004
7005            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7006                final UriPermission perm = it.next();
7007                if (perm.uri.sourceUserId == grantUri.sourceUserId
7008                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7009                    if (DEBUG_URI_PERMISSION)
7010                        Slog.v(TAG,
7011                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
7012                    persistChanged |= perm.revokeModes(
7013                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7014                    if (perm.modeFlags == 0) {
7015                        it.remove();
7016                    }
7017                }
7018            }
7019
7020            if (perms.isEmpty()) {
7021                mGrantedUriPermissions.remove(targetUid);
7022                N--;
7023                i--;
7024            }
7025        }
7026
7027        if (persistChanged) {
7028            schedulePersistUriGrants();
7029        }
7030    }
7031
7032    /**
7033     * @param uri This uri must NOT contain an embedded userId.
7034     * @param userId The userId in which the uri is to be resolved.
7035     */
7036    @Override
7037    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
7038            int userId) {
7039        enforceNotIsolatedCaller("revokeUriPermission");
7040        synchronized(this) {
7041            final ProcessRecord r = getRecordForAppLocked(caller);
7042            if (r == null) {
7043                throw new SecurityException("Unable to find app for caller "
7044                        + caller
7045                        + " when revoking permission to uri " + uri);
7046            }
7047            if (uri == null) {
7048                Slog.w(TAG, "revokeUriPermission: null uri");
7049                return;
7050            }
7051
7052            if (!Intent.isAccessUriMode(modeFlags)) {
7053                return;
7054            }
7055
7056            final IPackageManager pm = AppGlobals.getPackageManager();
7057            final String authority = uri.getAuthority();
7058            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
7059            if (pi == null) {
7060                Slog.w(TAG, "No content provider found for permission revoke: "
7061                        + uri.toSafeString());
7062                return;
7063            }
7064
7065            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
7066        }
7067    }
7068
7069    /**
7070     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
7071     * given package.
7072     *
7073     * @param packageName Package name to match, or {@code null} to apply to all
7074     *            packages.
7075     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
7076     *            to all users.
7077     * @param persistable If persistable grants should be removed.
7078     */
7079    private void removeUriPermissionsForPackageLocked(
7080            String packageName, int userHandle, boolean persistable) {
7081        if (userHandle == UserHandle.USER_ALL && packageName == null) {
7082            throw new IllegalArgumentException("Must narrow by either package or user");
7083        }
7084
7085        boolean persistChanged = false;
7086
7087        int N = mGrantedUriPermissions.size();
7088        for (int i = 0; i < N; i++) {
7089            final int targetUid = mGrantedUriPermissions.keyAt(i);
7090            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7091
7092            // Only inspect grants matching user
7093            if (userHandle == UserHandle.USER_ALL
7094                    || userHandle == UserHandle.getUserId(targetUid)) {
7095                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7096                    final UriPermission perm = it.next();
7097
7098                    // Only inspect grants matching package
7099                    if (packageName == null || perm.sourcePkg.equals(packageName)
7100                            || perm.targetPkg.equals(packageName)) {
7101                        persistChanged |= perm.revokeModes(persistable
7102                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7103
7104                        // Only remove when no modes remain; any persisted grants
7105                        // will keep this alive.
7106                        if (perm.modeFlags == 0) {
7107                            it.remove();
7108                        }
7109                    }
7110                }
7111
7112                if (perms.isEmpty()) {
7113                    mGrantedUriPermissions.remove(targetUid);
7114                    N--;
7115                    i--;
7116                }
7117            }
7118        }
7119
7120        if (persistChanged) {
7121            schedulePersistUriGrants();
7122        }
7123    }
7124
7125    @Override
7126    public IBinder newUriPermissionOwner(String name) {
7127        enforceNotIsolatedCaller("newUriPermissionOwner");
7128        synchronized(this) {
7129            UriPermissionOwner owner = new UriPermissionOwner(this, name);
7130            return owner.getExternalTokenLocked();
7131        }
7132    }
7133
7134    /**
7135     * @param uri This uri must NOT contain an embedded userId.
7136     * @param sourceUserId The userId in which the uri is to be resolved.
7137     * @param targetUserId The userId of the app that receives the grant.
7138     */
7139    @Override
7140    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
7141            final int modeFlags, int sourceUserId, int targetUserId) {
7142        targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
7143                targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null);
7144        synchronized(this) {
7145            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7146            if (owner == null) {
7147                throw new IllegalArgumentException("Unknown owner: " + token);
7148            }
7149            if (fromUid != Binder.getCallingUid()) {
7150                if (Binder.getCallingUid() != Process.myUid()) {
7151                    // Only system code can grant URI permissions on behalf
7152                    // of other users.
7153                    throw new SecurityException("nice try");
7154                }
7155            }
7156            if (targetPkg == null) {
7157                throw new IllegalArgumentException("null target");
7158            }
7159            if (uri == null) {
7160                throw new IllegalArgumentException("null uri");
7161            }
7162
7163            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
7164                    modeFlags, owner, targetUserId);
7165        }
7166    }
7167
7168    /**
7169     * @param uri This uri must NOT contain an embedded userId.
7170     * @param userId The userId in which the uri is to be resolved.
7171     */
7172    @Override
7173    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
7174        synchronized(this) {
7175            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7176            if (owner == null) {
7177                throw new IllegalArgumentException("Unknown owner: " + token);
7178            }
7179
7180            if (uri == null) {
7181                owner.removeUriPermissionsLocked(mode);
7182            } else {
7183                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
7184            }
7185        }
7186    }
7187
7188    private void schedulePersistUriGrants() {
7189        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
7190            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
7191                    10 * DateUtils.SECOND_IN_MILLIS);
7192        }
7193    }
7194
7195    private void writeGrantedUriPermissions() {
7196        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
7197
7198        // Snapshot permissions so we can persist without lock
7199        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
7200        synchronized (this) {
7201            final int size = mGrantedUriPermissions.size();
7202            for (int i = 0; i < size; i++) {
7203                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7204                for (UriPermission perm : perms.values()) {
7205                    if (perm.persistedModeFlags != 0) {
7206                        persist.add(perm.snapshot());
7207                    }
7208                }
7209            }
7210        }
7211
7212        FileOutputStream fos = null;
7213        try {
7214            fos = mGrantFile.startWrite();
7215
7216            XmlSerializer out = new FastXmlSerializer();
7217            out.setOutput(fos, "utf-8");
7218            out.startDocument(null, true);
7219            out.startTag(null, TAG_URI_GRANTS);
7220            for (UriPermission.Snapshot perm : persist) {
7221                out.startTag(null, TAG_URI_GRANT);
7222                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
7223                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
7224                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
7225                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
7226                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
7227                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
7228                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
7229                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
7230                out.endTag(null, TAG_URI_GRANT);
7231            }
7232            out.endTag(null, TAG_URI_GRANTS);
7233            out.endDocument();
7234
7235            mGrantFile.finishWrite(fos);
7236        } catch (IOException e) {
7237            if (fos != null) {
7238                mGrantFile.failWrite(fos);
7239            }
7240        }
7241    }
7242
7243    private void readGrantedUriPermissionsLocked() {
7244        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
7245
7246        final long now = System.currentTimeMillis();
7247
7248        FileInputStream fis = null;
7249        try {
7250            fis = mGrantFile.openRead();
7251            final XmlPullParser in = Xml.newPullParser();
7252            in.setInput(fis, null);
7253
7254            int type;
7255            while ((type = in.next()) != END_DOCUMENT) {
7256                final String tag = in.getName();
7257                if (type == START_TAG) {
7258                    if (TAG_URI_GRANT.equals(tag)) {
7259                        final int sourceUserId;
7260                        final int targetUserId;
7261                        final int userHandle = readIntAttribute(in,
7262                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
7263                        if (userHandle != UserHandle.USER_NULL) {
7264                            // For backwards compatibility.
7265                            sourceUserId = userHandle;
7266                            targetUserId = userHandle;
7267                        } else {
7268                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
7269                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
7270                        }
7271                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
7272                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
7273                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
7274                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
7275                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
7276                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
7277
7278                        // Sanity check that provider still belongs to source package
7279                        final ProviderInfo pi = getProviderInfoLocked(
7280                                uri.getAuthority(), sourceUserId);
7281                        if (pi != null && sourcePkg.equals(pi.packageName)) {
7282                            int targetUid = -1;
7283                            try {
7284                                targetUid = AppGlobals.getPackageManager()
7285                                        .getPackageUid(targetPkg, targetUserId);
7286                            } catch (RemoteException e) {
7287                            }
7288                            if (targetUid != -1) {
7289                                final UriPermission perm = findOrCreateUriPermissionLocked(
7290                                        sourcePkg, targetPkg, targetUid,
7291                                        new GrantUri(sourceUserId, uri, prefix));
7292                                perm.initPersistedModes(modeFlags, createdTime);
7293                            }
7294                        } else {
7295                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
7296                                    + " but instead found " + pi);
7297                        }
7298                    }
7299                }
7300            }
7301        } catch (FileNotFoundException e) {
7302            // Missing grants is okay
7303        } catch (IOException e) {
7304            Slog.wtf(TAG, "Failed reading Uri grants", e);
7305        } catch (XmlPullParserException e) {
7306            Slog.wtf(TAG, "Failed reading Uri grants", e);
7307        } finally {
7308            IoUtils.closeQuietly(fis);
7309        }
7310    }
7311
7312    /**
7313     * @param uri This uri must NOT contain an embedded userId.
7314     * @param userId The userId in which the uri is to be resolved.
7315     */
7316    @Override
7317    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7318        enforceNotIsolatedCaller("takePersistableUriPermission");
7319
7320        Preconditions.checkFlagsArgument(modeFlags,
7321                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7322
7323        synchronized (this) {
7324            final int callingUid = Binder.getCallingUid();
7325            boolean persistChanged = false;
7326            GrantUri grantUri = new GrantUri(userId, uri, false);
7327
7328            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7329                    new GrantUri(userId, uri, false));
7330            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7331                    new GrantUri(userId, uri, true));
7332
7333            final boolean exactValid = (exactPerm != null)
7334                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
7335            final boolean prefixValid = (prefixPerm != null)
7336                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
7337
7338            if (!(exactValid || prefixValid)) {
7339                throw new SecurityException("No persistable permission grants found for UID "
7340                        + callingUid + " and Uri " + grantUri.toSafeString());
7341            }
7342
7343            if (exactValid) {
7344                persistChanged |= exactPerm.takePersistableModes(modeFlags);
7345            }
7346            if (prefixValid) {
7347                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
7348            }
7349
7350            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
7351
7352            if (persistChanged) {
7353                schedulePersistUriGrants();
7354            }
7355        }
7356    }
7357
7358    /**
7359     * @param uri This uri must NOT contain an embedded userId.
7360     * @param userId The userId in which the uri is to be resolved.
7361     */
7362    @Override
7363    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7364        enforceNotIsolatedCaller("releasePersistableUriPermission");
7365
7366        Preconditions.checkFlagsArgument(modeFlags,
7367                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7368
7369        synchronized (this) {
7370            final int callingUid = Binder.getCallingUid();
7371            boolean persistChanged = false;
7372
7373            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7374                    new GrantUri(userId, uri, false));
7375            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7376                    new GrantUri(userId, uri, true));
7377            if (exactPerm == null && prefixPerm == null) {
7378                throw new SecurityException("No permission grants found for UID " + callingUid
7379                        + " and Uri " + uri.toSafeString());
7380            }
7381
7382            if (exactPerm != null) {
7383                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
7384                removeUriPermissionIfNeededLocked(exactPerm);
7385            }
7386            if (prefixPerm != null) {
7387                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
7388                removeUriPermissionIfNeededLocked(prefixPerm);
7389            }
7390
7391            if (persistChanged) {
7392                schedulePersistUriGrants();
7393            }
7394        }
7395    }
7396
7397    /**
7398     * Prune any older {@link UriPermission} for the given UID until outstanding
7399     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
7400     *
7401     * @return if any mutations occured that require persisting.
7402     */
7403    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
7404        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7405        if (perms == null) return false;
7406        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
7407
7408        final ArrayList<UriPermission> persisted = Lists.newArrayList();
7409        for (UriPermission perm : perms.values()) {
7410            if (perm.persistedModeFlags != 0) {
7411                persisted.add(perm);
7412            }
7413        }
7414
7415        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
7416        if (trimCount <= 0) return false;
7417
7418        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
7419        for (int i = 0; i < trimCount; i++) {
7420            final UriPermission perm = persisted.get(i);
7421
7422            if (DEBUG_URI_PERMISSION) {
7423                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
7424            }
7425
7426            perm.releasePersistableModes(~0);
7427            removeUriPermissionIfNeededLocked(perm);
7428        }
7429
7430        return true;
7431    }
7432
7433    @Override
7434    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
7435            String packageName, boolean incoming) {
7436        enforceNotIsolatedCaller("getPersistedUriPermissions");
7437        Preconditions.checkNotNull(packageName, "packageName");
7438
7439        final int callingUid = Binder.getCallingUid();
7440        final IPackageManager pm = AppGlobals.getPackageManager();
7441        try {
7442            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
7443            if (packageUid != callingUid) {
7444                throw new SecurityException(
7445                        "Package " + packageName + " does not belong to calling UID " + callingUid);
7446            }
7447        } catch (RemoteException e) {
7448            throw new SecurityException("Failed to verify package name ownership");
7449        }
7450
7451        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
7452        synchronized (this) {
7453            if (incoming) {
7454                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7455                        callingUid);
7456                if (perms == null) {
7457                    Slog.w(TAG, "No permission grants found for " + packageName);
7458                } else {
7459                    for (UriPermission perm : perms.values()) {
7460                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
7461                            result.add(perm.buildPersistedPublicApiObject());
7462                        }
7463                    }
7464                }
7465            } else {
7466                final int size = mGrantedUriPermissions.size();
7467                for (int i = 0; i < size; i++) {
7468                    final ArrayMap<GrantUri, UriPermission> perms =
7469                            mGrantedUriPermissions.valueAt(i);
7470                    for (UriPermission perm : perms.values()) {
7471                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
7472                            result.add(perm.buildPersistedPublicApiObject());
7473                        }
7474                    }
7475                }
7476            }
7477        }
7478        return new ParceledListSlice<android.content.UriPermission>(result);
7479    }
7480
7481    @Override
7482    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
7483        synchronized (this) {
7484            ProcessRecord app =
7485                who != null ? getRecordForAppLocked(who) : null;
7486            if (app == null) return;
7487
7488            Message msg = Message.obtain();
7489            msg.what = WAIT_FOR_DEBUGGER_MSG;
7490            msg.obj = app;
7491            msg.arg1 = waiting ? 1 : 0;
7492            mHandler.sendMessage(msg);
7493        }
7494    }
7495
7496    @Override
7497    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
7498        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
7499        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
7500        outInfo.availMem = Process.getFreeMemory();
7501        outInfo.totalMem = Process.getTotalMemory();
7502        outInfo.threshold = homeAppMem;
7503        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
7504        outInfo.hiddenAppThreshold = cachedAppMem;
7505        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
7506                ProcessList.SERVICE_ADJ);
7507        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
7508                ProcessList.VISIBLE_APP_ADJ);
7509        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
7510                ProcessList.FOREGROUND_APP_ADJ);
7511    }
7512
7513    // =========================================================
7514    // TASK MANAGEMENT
7515    // =========================================================
7516
7517    @Override
7518    public List<IAppTask> getAppTasks(String callingPackage) {
7519        int callingUid = Binder.getCallingUid();
7520        long ident = Binder.clearCallingIdentity();
7521
7522        synchronized(this) {
7523            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
7524            try {
7525                if (localLOGV) Slog.v(TAG, "getAppTasks");
7526
7527                final int N = mRecentTasks.size();
7528                for (int i = 0; i < N; i++) {
7529                    TaskRecord tr = mRecentTasks.get(i);
7530                    // Skip tasks that do not match the caller.  We don't need to verify
7531                    // callingPackage, because we are also limiting to callingUid and know
7532                    // that will limit to the correct security sandbox.
7533                    if (tr.effectiveUid != callingUid) {
7534                        continue;
7535                    }
7536                    Intent intent = tr.getBaseIntent();
7537                    if (intent == null ||
7538                            !callingPackage.equals(intent.getComponent().getPackageName())) {
7539                        continue;
7540                    }
7541                    ActivityManager.RecentTaskInfo taskInfo =
7542                            createRecentTaskInfoFromTaskRecord(tr);
7543                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
7544                    list.add(taskImpl);
7545                }
7546            } finally {
7547                Binder.restoreCallingIdentity(ident);
7548            }
7549            return list;
7550        }
7551    }
7552
7553    @Override
7554    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
7555        final int callingUid = Binder.getCallingUid();
7556        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
7557
7558        synchronized(this) {
7559            if (localLOGV) Slog.v(
7560                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
7561
7562            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
7563                    callingUid);
7564
7565            // TODO: Improve with MRU list from all ActivityStacks.
7566            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
7567        }
7568
7569        return list;
7570    }
7571
7572    /**
7573     * Creates a new RecentTaskInfo from a TaskRecord.
7574     */
7575    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
7576        // Update the task description to reflect any changes in the task stack
7577        tr.updateTaskDescription();
7578
7579        // Compose the recent task info
7580        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
7581        rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
7582        rti.persistentId = tr.taskId;
7583        rti.baseIntent = new Intent(tr.getBaseIntent());
7584        rti.origActivity = tr.origActivity;
7585        rti.description = tr.lastDescription;
7586        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
7587        rti.userId = tr.userId;
7588        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
7589        rti.firstActiveTime = tr.firstActiveTime;
7590        rti.lastActiveTime = tr.lastActiveTime;
7591        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
7592        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
7593        return rti;
7594    }
7595
7596    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
7597        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
7598                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
7599        if (!allowed) {
7600            if (checkPermission(android.Manifest.permission.GET_TASKS,
7601                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
7602                // Temporary compatibility: some existing apps on the system image may
7603                // still be requesting the old permission and not switched to the new
7604                // one; if so, we'll still allow them full access.  This means we need
7605                // to see if they are holding the old permission and are a system app.
7606                try {
7607                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
7608                        allowed = true;
7609                        Slog.w(TAG, caller + ": caller " + callingUid
7610                                + " is using old GET_TASKS but privileged; allowing");
7611                    }
7612                } catch (RemoteException e) {
7613                }
7614            }
7615        }
7616        if (!allowed) {
7617            Slog.w(TAG, caller + ": caller " + callingUid
7618                    + " does not hold GET_TASKS; limiting output");
7619        }
7620        return allowed;
7621    }
7622
7623    @Override
7624    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
7625        final int callingUid = Binder.getCallingUid();
7626        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7627                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
7628
7629        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
7630        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
7631        synchronized (this) {
7632            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
7633                    callingUid);
7634            final boolean detailed = checkCallingPermission(
7635                    android.Manifest.permission.GET_DETAILED_TASKS)
7636                    == PackageManager.PERMISSION_GRANTED;
7637
7638            final int N = mRecentTasks.size();
7639            ArrayList<ActivityManager.RecentTaskInfo> res
7640                    = new ArrayList<ActivityManager.RecentTaskInfo>(
7641                            maxNum < N ? maxNum : N);
7642
7643            final Set<Integer> includedUsers;
7644            if (includeProfiles) {
7645                includedUsers = getProfileIdsLocked(userId);
7646            } else {
7647                includedUsers = new HashSet<Integer>();
7648            }
7649            includedUsers.add(Integer.valueOf(userId));
7650
7651            for (int i=0; i<N && maxNum > 0; i++) {
7652                TaskRecord tr = mRecentTasks.get(i);
7653                // Only add calling user or related users recent tasks
7654                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
7655                    if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr);
7656                    continue;
7657                }
7658
7659                // Return the entry if desired by the caller.  We always return
7660                // the first entry, because callers always expect this to be the
7661                // foreground app.  We may filter others if the caller has
7662                // not supplied RECENT_WITH_EXCLUDED and there is some reason
7663                // we should exclude the entry.
7664
7665                if (i == 0
7666                        || withExcluded
7667                        || (tr.intent == null)
7668                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
7669                                == 0)) {
7670                    if (!allowed) {
7671                        // If the caller doesn't have the GET_TASKS permission, then only
7672                        // allow them to see a small subset of tasks -- their own and home.
7673                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
7674                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr);
7675                            continue;
7676                        }
7677                    }
7678                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
7679                        if (tr.stack != null && tr.stack.isHomeStack()) {
7680                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr);
7681                            continue;
7682                        }
7683                    }
7684                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
7685                        // Don't include auto remove tasks that are finished or finishing.
7686                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: "
7687                                + tr);
7688                        continue;
7689                    }
7690                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
7691                            && !tr.isAvailable) {
7692                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr);
7693                        continue;
7694                    }
7695
7696                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
7697                    if (!detailed) {
7698                        rti.baseIntent.replaceExtras((Bundle)null);
7699                    }
7700
7701                    res.add(rti);
7702                    maxNum--;
7703                }
7704            }
7705            return res;
7706        }
7707    }
7708
7709    @Override
7710    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
7711        synchronized (this) {
7712            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
7713                    "getTaskThumbnail()");
7714            TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(id);
7715            if (tr != null) {
7716                return tr.getTaskThumbnailLocked();
7717            }
7718        }
7719        return null;
7720    }
7721
7722    @Override
7723    public int addAppTask(IBinder activityToken, Intent intent,
7724            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
7725        final int callingUid = Binder.getCallingUid();
7726        final long callingIdent = Binder.clearCallingIdentity();
7727
7728        try {
7729            synchronized (this) {
7730                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
7731                if (r == null) {
7732                    throw new IllegalArgumentException("Activity does not exist; token="
7733                            + activityToken);
7734                }
7735                ComponentName comp = intent.getComponent();
7736                if (comp == null) {
7737                    throw new IllegalArgumentException("Intent " + intent
7738                            + " must specify explicit component");
7739                }
7740                if (thumbnail.getWidth() != mThumbnailWidth
7741                        || thumbnail.getHeight() != mThumbnailHeight) {
7742                    throw new IllegalArgumentException("Bad thumbnail size: got "
7743                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
7744                            + mThumbnailWidth + "x" + mThumbnailHeight);
7745                }
7746                if (intent.getSelector() != null) {
7747                    intent.setSelector(null);
7748                }
7749                if (intent.getSourceBounds() != null) {
7750                    intent.setSourceBounds(null);
7751                }
7752                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
7753                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
7754                        // The caller has added this as an auto-remove task...  that makes no
7755                        // sense, so turn off auto-remove.
7756                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
7757                    }
7758                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
7759                    // Must be a new task.
7760                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
7761                }
7762                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
7763                    mLastAddedTaskActivity = null;
7764                }
7765                ActivityInfo ainfo = mLastAddedTaskActivity;
7766                if (ainfo == null) {
7767                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
7768                            comp, 0, UserHandle.getUserId(callingUid));
7769                    if (ainfo.applicationInfo.uid != callingUid) {
7770                        throw new SecurityException(
7771                                "Can't add task for another application: target uid="
7772                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
7773                    }
7774                }
7775
7776                TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo,
7777                        intent, description);
7778
7779                int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
7780                if (trimIdx >= 0) {
7781                    // If this would have caused a trim, then we'll abort because that
7782                    // means it would be added at the end of the list but then just removed.
7783                    return INVALID_TASK_ID;
7784                }
7785
7786                final int N = mRecentTasks.size();
7787                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
7788                    final TaskRecord tr = mRecentTasks.remove(N - 1);
7789                    tr.removedFromRecents();
7790                }
7791
7792                task.inRecents = true;
7793                mRecentTasks.add(task);
7794                r.task.stack.addTask(task, false, false);
7795
7796                task.setLastThumbnail(thumbnail);
7797                task.freeLastThumbnail();
7798
7799                return task.taskId;
7800            }
7801        } finally {
7802            Binder.restoreCallingIdentity(callingIdent);
7803        }
7804    }
7805
7806    @Override
7807    public Point getAppTaskThumbnailSize() {
7808        synchronized (this) {
7809            return new Point(mThumbnailWidth,  mThumbnailHeight);
7810        }
7811    }
7812
7813    @Override
7814    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
7815        synchronized (this) {
7816            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7817            if (r != null) {
7818                r.setTaskDescription(td);
7819                r.task.updateTaskDescription();
7820            }
7821        }
7822    }
7823
7824    @Override
7825    public Bitmap getTaskDescriptionIcon(String filename) {
7826        if (!FileUtils.isValidExtFilename(filename)
7827                || !filename.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
7828            throw new IllegalArgumentException("Bad filename: " + filename);
7829        }
7830        return mTaskPersister.getTaskDescriptionIcon(filename);
7831    }
7832
7833    @Override
7834    public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
7835            throws RemoteException {
7836        if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
7837                opts.getCustomInPlaceResId() == 0) {
7838            throw new IllegalArgumentException("Expected in-place ActivityOption " +
7839                    "with valid animation");
7840        }
7841        mWindowManager.prepareAppTransition(AppTransition.TRANSIT_TASK_IN_PLACE, false);
7842        mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
7843                opts.getCustomInPlaceResId());
7844        mWindowManager.executeAppTransition();
7845    }
7846
7847    private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess) {
7848        mRecentTasks.remove(tr);
7849        tr.removedFromRecents();
7850        ComponentName component = tr.getBaseIntent().getComponent();
7851        if (component == null) {
7852            Slog.w(TAG, "No component for base intent of task: " + tr);
7853            return;
7854        }
7855
7856        if (!killProcess) {
7857            return;
7858        }
7859
7860        // Determine if the process(es) for this task should be killed.
7861        final String pkg = component.getPackageName();
7862        ArrayList<ProcessRecord> procsToKill = new ArrayList<ProcessRecord>();
7863        ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
7864        for (int i = 0; i < pmap.size(); i++) {
7865
7866            SparseArray<ProcessRecord> uids = pmap.valueAt(i);
7867            for (int j = 0; j < uids.size(); j++) {
7868                ProcessRecord proc = uids.valueAt(j);
7869                if (proc.userId != tr.userId) {
7870                    // Don't kill process for a different user.
7871                    continue;
7872                }
7873                if (proc == mHomeProcess) {
7874                    // Don't kill the home process along with tasks from the same package.
7875                    continue;
7876                }
7877                if (!proc.pkgList.containsKey(pkg)) {
7878                    // Don't kill process that is not associated with this task.
7879                    continue;
7880                }
7881
7882                for (int k = 0; k < proc.activities.size(); k++) {
7883                    TaskRecord otherTask = proc.activities.get(k).task;
7884                    if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
7885                        // Don't kill process(es) that has an activity in a different task that is
7886                        // also in recents.
7887                        return;
7888                    }
7889                }
7890
7891                // Add process to kill list.
7892                procsToKill.add(proc);
7893            }
7894        }
7895
7896        // Find any running services associated with this app and stop if needed.
7897        mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
7898
7899        // Kill the running processes.
7900        for (int i = 0; i < procsToKill.size(); i++) {
7901            ProcessRecord pr = procsToKill.get(i);
7902            if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
7903                pr.kill("remove task", true);
7904            } else {
7905                pr.waitingToKill = "remove task";
7906            }
7907        }
7908    }
7909
7910    private void removeTasksByPackageNameLocked(String packageName, int userId) {
7911        // Remove all tasks with activities in the specified package from the list of recent tasks
7912        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
7913            TaskRecord tr = mRecentTasks.get(i);
7914            if (tr.userId != userId) continue;
7915
7916            ComponentName cn = tr.intent.getComponent();
7917            if (cn != null && cn.getPackageName().equals(packageName)) {
7918                // If the package name matches, remove the task.
7919                removeTaskByIdLocked(tr.taskId, true);
7920            }
7921        }
7922    }
7923
7924    private void removeTasksByRemovedPackageComponentsLocked(String packageName, int userId) {
7925        final IPackageManager pm = AppGlobals.getPackageManager();
7926        final HashSet<ComponentName> componentsKnownToExist = new HashSet<ComponentName>();
7927
7928        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
7929            TaskRecord tr = mRecentTasks.get(i);
7930            if (tr.userId != userId) continue;
7931
7932            ComponentName cn = tr.intent.getComponent();
7933            if (cn != null && cn.getPackageName().equals(packageName)) {
7934                // Skip if component still exists in the package.
7935                if (componentsKnownToExist.contains(cn)) continue;
7936
7937                try {
7938                    ActivityInfo info = pm.getActivityInfo(cn, 0, userId);
7939                    if (info != null) {
7940                        componentsKnownToExist.add(cn);
7941                    } else {
7942                        removeTaskByIdLocked(tr.taskId, false);
7943                    }
7944                } catch (RemoteException e) {
7945                    Log.e(TAG, "Activity info query failed. component=" + cn, e);
7946                }
7947            }
7948        }
7949    }
7950
7951    /**
7952     * Removes the task with the specified task id.
7953     *
7954     * @param taskId Identifier of the task to be removed.
7955     * @param killProcess Kill any process associated with the task if possible.
7956     * @return Returns true if the given task was found and removed.
7957     */
7958    private boolean removeTaskByIdLocked(int taskId, boolean killProcess) {
7959        TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(taskId);
7960        if (tr != null) {
7961            tr.removeTaskActivitiesLocked();
7962            cleanUpRemovedTaskLocked(tr, killProcess);
7963            if (tr.isPersistable) {
7964                notifyTaskPersisterLocked(null, true);
7965            }
7966            return true;
7967        }
7968        Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
7969        return false;
7970    }
7971
7972    @Override
7973    public boolean removeTask(int taskId) {
7974        synchronized (this) {
7975            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7976                    "removeTask()");
7977            long ident = Binder.clearCallingIdentity();
7978            try {
7979                return removeTaskByIdLocked(taskId, true);
7980            } finally {
7981                Binder.restoreCallingIdentity(ident);
7982            }
7983        }
7984    }
7985
7986    /**
7987     * TODO: Add mController hook
7988     */
7989    @Override
7990    public void moveTaskToFront(int taskId, int flags, Bundle options) {
7991        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7992                "moveTaskToFront()");
7993
7994        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
7995        synchronized(this) {
7996            moveTaskToFrontLocked(taskId, flags, options);
7997        }
7998    }
7999
8000    void moveTaskToFrontLocked(int taskId, int flags, Bundle options) {
8001        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8002                Binder.getCallingUid(), -1, -1, "Task to front")) {
8003            ActivityOptions.abort(options);
8004            return;
8005        }
8006        final long origId = Binder.clearCallingIdentity();
8007        try {
8008            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8009            if (task == null) {
8010                Slog.d(TAG, "Could not find task for id: "+ taskId);
8011                return;
8012            }
8013            if (mStackSupervisor.isLockTaskModeViolation(task)) {
8014                mStackSupervisor.showLockTaskToast();
8015                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
8016                return;
8017            }
8018            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
8019            if (prev != null && prev.isRecentsActivity()) {
8020                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
8021            }
8022            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
8023        } finally {
8024            Binder.restoreCallingIdentity(origId);
8025        }
8026        ActivityOptions.abort(options);
8027    }
8028
8029    /**
8030     * Moves an activity, and all of the other activities within the same task, to the bottom
8031     * of the history stack.  The activity's order within the task is unchanged.
8032     *
8033     * @param token A reference to the activity we wish to move
8034     * @param nonRoot If false then this only works if the activity is the root
8035     *                of a task; if true it will work for any activity in a task.
8036     * @return Returns true if the move completed, false if not.
8037     */
8038    @Override
8039    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
8040        enforceNotIsolatedCaller("moveActivityTaskToBack");
8041        synchronized(this) {
8042            final long origId = Binder.clearCallingIdentity();
8043            try {
8044                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
8045                if (taskId >= 0) {
8046                    if ((mStackSupervisor.mLockTaskModeTask != null)
8047                            && (mStackSupervisor.mLockTaskModeTask.taskId == taskId)) {
8048                        mStackSupervisor.showLockTaskToast();
8049                        return false;
8050                    }
8051                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
8052                }
8053            } finally {
8054                Binder.restoreCallingIdentity(origId);
8055            }
8056        }
8057        return false;
8058    }
8059
8060    @Override
8061    public void moveTaskBackwards(int task) {
8062        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8063                "moveTaskBackwards()");
8064
8065        synchronized(this) {
8066            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8067                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
8068                return;
8069            }
8070            final long origId = Binder.clearCallingIdentity();
8071            moveTaskBackwardsLocked(task);
8072            Binder.restoreCallingIdentity(origId);
8073        }
8074    }
8075
8076    private final void moveTaskBackwardsLocked(int task) {
8077        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
8078    }
8079
8080    @Override
8081    public IBinder getHomeActivityToken() throws RemoteException {
8082        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8083                "getHomeActivityToken()");
8084        synchronized (this) {
8085            return mStackSupervisor.getHomeActivityToken();
8086        }
8087    }
8088
8089    @Override
8090    public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
8091            IActivityContainerCallback callback) throws RemoteException {
8092        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8093                "createActivityContainer()");
8094        synchronized (this) {
8095            if (parentActivityToken == null) {
8096                throw new IllegalArgumentException("parent token must not be null");
8097            }
8098            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
8099            if (r == null) {
8100                return null;
8101            }
8102            if (callback == null) {
8103                throw new IllegalArgumentException("callback must not be null");
8104            }
8105            return mStackSupervisor.createVirtualActivityContainer(r, callback);
8106        }
8107    }
8108
8109    @Override
8110    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
8111        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8112                "deleteActivityContainer()");
8113        synchronized (this) {
8114            mStackSupervisor.deleteActivityContainer(container);
8115        }
8116    }
8117
8118    @Override
8119    public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
8120        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8121                "createStackOnDisplay()");
8122        synchronized (this) {
8123            final int stackId = mStackSupervisor.getNextStackId();
8124            final ActivityStack stack = mStackSupervisor.createStackOnDisplay(stackId, displayId);
8125            if (stack == null) {
8126                return null;
8127            }
8128            return stack.mActivityContainer;
8129        }
8130    }
8131
8132    @Override
8133    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
8134            throws RemoteException {
8135        synchronized (this) {
8136            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
8137            if (stack != null) {
8138                return stack.mActivityContainer;
8139            }
8140            return null;
8141        }
8142    }
8143
8144    @Override
8145    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
8146        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8147                "moveTaskToStack()");
8148        if (stackId == HOME_STACK_ID) {
8149            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
8150                    new RuntimeException("here").fillInStackTrace());
8151        }
8152        synchronized (this) {
8153            long ident = Binder.clearCallingIdentity();
8154            try {
8155                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
8156                        + stackId + " toTop=" + toTop);
8157                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
8158            } finally {
8159                Binder.restoreCallingIdentity(ident);
8160            }
8161        }
8162    }
8163
8164    @Override
8165    public void resizeStack(int stackBoxId, Rect bounds) {
8166        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8167                "resizeStackBox()");
8168        long ident = Binder.clearCallingIdentity();
8169        try {
8170            mWindowManager.resizeStack(stackBoxId, bounds);
8171        } finally {
8172            Binder.restoreCallingIdentity(ident);
8173        }
8174    }
8175
8176    @Override
8177    public List<StackInfo> getAllStackInfos() {
8178        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8179                "getAllStackInfos()");
8180        long ident = Binder.clearCallingIdentity();
8181        try {
8182            synchronized (this) {
8183                return mStackSupervisor.getAllStackInfosLocked();
8184            }
8185        } finally {
8186            Binder.restoreCallingIdentity(ident);
8187        }
8188    }
8189
8190    @Override
8191    public StackInfo getStackInfo(int stackId) {
8192        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8193                "getStackInfo()");
8194        long ident = Binder.clearCallingIdentity();
8195        try {
8196            synchronized (this) {
8197                return mStackSupervisor.getStackInfoLocked(stackId);
8198            }
8199        } finally {
8200            Binder.restoreCallingIdentity(ident);
8201        }
8202    }
8203
8204    @Override
8205    public boolean isInHomeStack(int taskId) {
8206        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8207                "getStackInfo()");
8208        long ident = Binder.clearCallingIdentity();
8209        try {
8210            synchronized (this) {
8211                TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(taskId);
8212                return tr != null && tr.stack != null && tr.stack.isHomeStack();
8213            }
8214        } finally {
8215            Binder.restoreCallingIdentity(ident);
8216        }
8217    }
8218
8219    @Override
8220    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
8221        synchronized(this) {
8222            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
8223        }
8224    }
8225
8226    private boolean isLockTaskAuthorized(String pkg) {
8227        final DevicePolicyManager dpm = (DevicePolicyManager)
8228                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
8229        try {
8230            int uid = mContext.getPackageManager().getPackageUid(pkg,
8231                    Binder.getCallingUserHandle().getIdentifier());
8232            return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
8233        } catch (NameNotFoundException e) {
8234            return false;
8235        }
8236    }
8237
8238    void startLockTaskMode(TaskRecord task) {
8239        final String pkg;
8240        synchronized (this) {
8241            pkg = task.intent.getComponent().getPackageName();
8242        }
8243        boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID;
8244        if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) {
8245            StatusBarManagerInternal statusBarManager = LocalServices.getService(
8246                    StatusBarManagerInternal.class);
8247            if (statusBarManager != null) {
8248                statusBarManager.showScreenPinningRequest();
8249            }
8250            return;
8251        }
8252        long ident = Binder.clearCallingIdentity();
8253        try {
8254            synchronized (this) {
8255                // Since we lost lock on task, make sure it is still there.
8256                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
8257                if (task != null) {
8258                    if (!isSystemInitiated
8259                            && ((mStackSupervisor.getFocusedStack() == null)
8260                                    || (task != mStackSupervisor.getFocusedStack().topTask()))) {
8261                        throw new IllegalArgumentException("Invalid task, not in foreground");
8262                    }
8263                    mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated);
8264                }
8265            }
8266        } finally {
8267            Binder.restoreCallingIdentity(ident);
8268        }
8269    }
8270
8271    @Override
8272    public void startLockTaskMode(int taskId) {
8273        final TaskRecord task;
8274        long ident = Binder.clearCallingIdentity();
8275        try {
8276            synchronized (this) {
8277                task = mStackSupervisor.anyTaskForIdLocked(taskId);
8278            }
8279        } finally {
8280            Binder.restoreCallingIdentity(ident);
8281        }
8282        if (task != null) {
8283            startLockTaskMode(task);
8284        }
8285    }
8286
8287    @Override
8288    public void startLockTaskMode(IBinder token) {
8289        final TaskRecord task;
8290        long ident = Binder.clearCallingIdentity();
8291        try {
8292            synchronized (this) {
8293                final ActivityRecord r = ActivityRecord.forToken(token);
8294                if (r == null) {
8295                    return;
8296                }
8297                task = r.task;
8298            }
8299        } finally {
8300            Binder.restoreCallingIdentity(ident);
8301        }
8302        if (task != null) {
8303            startLockTaskMode(task);
8304        }
8305    }
8306
8307    @Override
8308    public void startLockTaskModeOnCurrent() throws RemoteException {
8309        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8310                "startLockTaskModeOnCurrent");
8311        long ident = Binder.clearCallingIdentity();
8312        try {
8313            ActivityRecord r = null;
8314            synchronized (this) {
8315                r = mStackSupervisor.topRunningActivityLocked();
8316            }
8317            startLockTaskMode(r.task);
8318        } finally {
8319            Binder.restoreCallingIdentity(ident);
8320        }
8321    }
8322
8323    @Override
8324    public void stopLockTaskMode() {
8325        // Verify that the user matches the package of the intent for the TaskRecord
8326        // we are locked to or systtem.  This will ensure the same caller for startLockTaskMode
8327        // and stopLockTaskMode.
8328        final int callingUid = Binder.getCallingUid();
8329        if (callingUid != Process.SYSTEM_UID) {
8330            try {
8331                String pkg =
8332                        mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName();
8333                int uid = mContext.getPackageManager().getPackageUid(pkg,
8334                        Binder.getCallingUserHandle().getIdentifier());
8335                if (uid != callingUid) {
8336                    throw new SecurityException("Invalid uid, expected " + uid);
8337                }
8338            } catch (NameNotFoundException e) {
8339                Log.d(TAG, "stopLockTaskMode " + e);
8340                return;
8341            }
8342        }
8343        long ident = Binder.clearCallingIdentity();
8344        try {
8345            Log.d(TAG, "stopLockTaskMode");
8346            // Stop lock task
8347            synchronized (this) {
8348                mStackSupervisor.setLockTaskModeLocked(null, false);
8349            }
8350        } finally {
8351            Binder.restoreCallingIdentity(ident);
8352        }
8353    }
8354
8355    @Override
8356    public void stopLockTaskModeOnCurrent() throws RemoteException {
8357        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8358                "stopLockTaskModeOnCurrent");
8359        long ident = Binder.clearCallingIdentity();
8360        try {
8361            stopLockTaskMode();
8362        } finally {
8363            Binder.restoreCallingIdentity(ident);
8364        }
8365    }
8366
8367    @Override
8368    public boolean isInLockTaskMode() {
8369        synchronized (this) {
8370            return mStackSupervisor.isInLockTaskMode();
8371        }
8372    }
8373
8374    // =========================================================
8375    // CONTENT PROVIDERS
8376    // =========================================================
8377
8378    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
8379        List<ProviderInfo> providers = null;
8380        try {
8381            providers = AppGlobals.getPackageManager().
8382                queryContentProviders(app.processName, app.uid,
8383                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
8384        } catch (RemoteException ex) {
8385        }
8386        if (DEBUG_MU)
8387            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
8388        int userId = app.userId;
8389        if (providers != null) {
8390            int N = providers.size();
8391            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
8392            for (int i=0; i<N; i++) {
8393                ProviderInfo cpi =
8394                    (ProviderInfo)providers.get(i);
8395                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8396                        cpi.name, cpi.flags);
8397                if (singleton && UserHandle.getUserId(app.uid) != 0) {
8398                    // This is a singleton provider, but a user besides the
8399                    // default user is asking to initialize a process it runs
8400                    // in...  well, no, it doesn't actually run in this process,
8401                    // it runs in the process of the default user.  Get rid of it.
8402                    providers.remove(i);
8403                    N--;
8404                    i--;
8405                    continue;
8406                }
8407
8408                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8409                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
8410                if (cpr == null) {
8411                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
8412                    mProviderMap.putProviderByClass(comp, cpr);
8413                }
8414                if (DEBUG_MU)
8415                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
8416                app.pubProviders.put(cpi.name, cpr);
8417                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
8418                    // Don't add this if it is a platform component that is marked
8419                    // to run in multiple processes, because this is actually
8420                    // part of the framework so doesn't make sense to track as a
8421                    // separate apk in the process.
8422                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
8423                            mProcessStats);
8424                }
8425                ensurePackageDexOpt(cpi.applicationInfo.packageName);
8426            }
8427        }
8428        return providers;
8429    }
8430
8431    /**
8432     * Check if {@link ProcessRecord} has a possible chance at accessing the
8433     * given {@link ProviderInfo}. Final permission checking is always done
8434     * in {@link ContentProvider}.
8435     */
8436    private final String checkContentProviderPermissionLocked(
8437            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
8438        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
8439        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
8440        boolean checkedGrants = false;
8441        if (checkUser) {
8442            // Looking for cross-user grants before enforcing the typical cross-users permissions
8443            int tmpTargetUserId = unsafeConvertIncomingUser(userId);
8444            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
8445                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
8446                    return null;
8447                }
8448                checkedGrants = true;
8449            }
8450            userId = handleIncomingUser(callingPid, callingUid, userId,
8451                    false, ALLOW_NON_FULL,
8452                    "checkContentProviderPermissionLocked " + cpi.authority, null);
8453            if (userId != tmpTargetUserId) {
8454                // When we actually went to determine the final targer user ID, this ended
8455                // up different than our initial check for the authority.  This is because
8456                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
8457                // SELF.  So we need to re-check the grants again.
8458                checkedGrants = false;
8459            }
8460        }
8461        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
8462                cpi.applicationInfo.uid, cpi.exported)
8463                == PackageManager.PERMISSION_GRANTED) {
8464            return null;
8465        }
8466        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
8467                cpi.applicationInfo.uid, cpi.exported)
8468                == PackageManager.PERMISSION_GRANTED) {
8469            return null;
8470        }
8471
8472        PathPermission[] pps = cpi.pathPermissions;
8473        if (pps != null) {
8474            int i = pps.length;
8475            while (i > 0) {
8476                i--;
8477                PathPermission pp = pps[i];
8478                String pprperm = pp.getReadPermission();
8479                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
8480                        cpi.applicationInfo.uid, cpi.exported)
8481                        == PackageManager.PERMISSION_GRANTED) {
8482                    return null;
8483                }
8484                String ppwperm = pp.getWritePermission();
8485                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
8486                        cpi.applicationInfo.uid, cpi.exported)
8487                        == PackageManager.PERMISSION_GRANTED) {
8488                    return null;
8489                }
8490            }
8491        }
8492        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
8493            return null;
8494        }
8495
8496        String msg;
8497        if (!cpi.exported) {
8498            msg = "Permission Denial: opening provider " + cpi.name
8499                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8500                    + ", uid=" + callingUid + ") that is not exported from uid "
8501                    + cpi.applicationInfo.uid;
8502        } else {
8503            msg = "Permission Denial: opening provider " + cpi.name
8504                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8505                    + ", uid=" + callingUid + ") requires "
8506                    + cpi.readPermission + " or " + cpi.writePermission;
8507        }
8508        Slog.w(TAG, msg);
8509        return msg;
8510    }
8511
8512    /**
8513     * Returns if the ContentProvider has granted a uri to callingUid
8514     */
8515    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
8516        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8517        if (perms != null) {
8518            for (int i=perms.size()-1; i>=0; i--) {
8519                GrantUri grantUri = perms.keyAt(i);
8520                if (grantUri.sourceUserId == userId || !checkUser) {
8521                    if (matchesProvider(grantUri.uri, cpi)) {
8522                        return true;
8523                    }
8524                }
8525            }
8526        }
8527        return false;
8528    }
8529
8530    /**
8531     * Returns true if the uri authority is one of the authorities specified in the provider.
8532     */
8533    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
8534        String uriAuth = uri.getAuthority();
8535        String cpiAuth = cpi.authority;
8536        if (cpiAuth.indexOf(';') == -1) {
8537            return cpiAuth.equals(uriAuth);
8538        }
8539        String[] cpiAuths = cpiAuth.split(";");
8540        int length = cpiAuths.length;
8541        for (int i = 0; i < length; i++) {
8542            if (cpiAuths[i].equals(uriAuth)) return true;
8543        }
8544        return false;
8545    }
8546
8547    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
8548            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8549        if (r != null) {
8550            for (int i=0; i<r.conProviders.size(); i++) {
8551                ContentProviderConnection conn = r.conProviders.get(i);
8552                if (conn.provider == cpr) {
8553                    if (DEBUG_PROVIDER) Slog.v(TAG,
8554                            "Adding provider requested by "
8555                            + r.processName + " from process "
8556                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8557                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8558                    if (stable) {
8559                        conn.stableCount++;
8560                        conn.numStableIncs++;
8561                    } else {
8562                        conn.unstableCount++;
8563                        conn.numUnstableIncs++;
8564                    }
8565                    return conn;
8566                }
8567            }
8568            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
8569            if (stable) {
8570                conn.stableCount = 1;
8571                conn.numStableIncs = 1;
8572            } else {
8573                conn.unstableCount = 1;
8574                conn.numUnstableIncs = 1;
8575            }
8576            cpr.connections.add(conn);
8577            r.conProviders.add(conn);
8578            startAssociationLocked(r.uid, r.processName, cpr.uid, cpr.name, cpr.info.processName);
8579            return conn;
8580        }
8581        cpr.addExternalProcessHandleLocked(externalProcessToken);
8582        return null;
8583    }
8584
8585    boolean decProviderCountLocked(ContentProviderConnection conn,
8586            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8587        if (conn != null) {
8588            cpr = conn.provider;
8589            if (DEBUG_PROVIDER) Slog.v(TAG,
8590                    "Removing provider requested by "
8591                    + conn.client.processName + " from process "
8592                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8593                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8594            if (stable) {
8595                conn.stableCount--;
8596            } else {
8597                conn.unstableCount--;
8598            }
8599            if (conn.stableCount == 0 && conn.unstableCount == 0) {
8600                cpr.connections.remove(conn);
8601                conn.client.conProviders.remove(conn);
8602                stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
8603                return true;
8604            }
8605            return false;
8606        }
8607        cpr.removeExternalProcessHandleLocked(externalProcessToken);
8608        return false;
8609    }
8610
8611    private void checkTime(long startTime, String where) {
8612        long now = SystemClock.elapsedRealtime();
8613        if ((now-startTime) > 1000) {
8614            // If we are taking more than a second, log about it.
8615            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
8616        }
8617    }
8618
8619    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
8620            String name, IBinder token, boolean stable, int userId) {
8621        ContentProviderRecord cpr;
8622        ContentProviderConnection conn = null;
8623        ProviderInfo cpi = null;
8624
8625        synchronized(this) {
8626            long startTime = SystemClock.elapsedRealtime();
8627
8628            ProcessRecord r = null;
8629            if (caller != null) {
8630                r = getRecordForAppLocked(caller);
8631                if (r == null) {
8632                    throw new SecurityException(
8633                            "Unable to find app for caller " + caller
8634                          + " (pid=" + Binder.getCallingPid()
8635                          + ") when getting content provider " + name);
8636                }
8637            }
8638
8639            boolean checkCrossUser = true;
8640
8641            checkTime(startTime, "getContentProviderImpl: getProviderByName");
8642
8643            // First check if this content provider has been published...
8644            cpr = mProviderMap.getProviderByName(name, userId);
8645            // If that didn't work, check if it exists for user 0 and then
8646            // verify that it's a singleton provider before using it.
8647            if (cpr == null && userId != UserHandle.USER_OWNER) {
8648                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
8649                if (cpr != null) {
8650                    cpi = cpr.info;
8651                    if (isSingleton(cpi.processName, cpi.applicationInfo,
8652                            cpi.name, cpi.flags)
8653                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
8654                        userId = UserHandle.USER_OWNER;
8655                        checkCrossUser = false;
8656                    } else {
8657                        cpr = null;
8658                        cpi = null;
8659                    }
8660                }
8661            }
8662
8663            boolean providerRunning = cpr != null;
8664            if (providerRunning) {
8665                cpi = cpr.info;
8666                String msg;
8667                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
8668                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
8669                        != null) {
8670                    throw new SecurityException(msg);
8671                }
8672                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
8673
8674                if (r != null && cpr.canRunHere(r)) {
8675                    // This provider has been published or is in the process
8676                    // of being published...  but it is also allowed to run
8677                    // in the caller's process, so don't make a connection
8678                    // and just let the caller instantiate its own instance.
8679                    ContentProviderHolder holder = cpr.newHolder(null);
8680                    // don't give caller the provider object, it needs
8681                    // to make its own.
8682                    holder.provider = null;
8683                    return holder;
8684                }
8685
8686                final long origId = Binder.clearCallingIdentity();
8687
8688                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
8689
8690                // In this case the provider instance already exists, so we can
8691                // return it right away.
8692                conn = incProviderCountLocked(r, cpr, token, stable);
8693                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
8694                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
8695                        // If this is a perceptible app accessing the provider,
8696                        // make sure to count it as being accessed and thus
8697                        // back up on the LRU list.  This is good because
8698                        // content providers are often expensive to start.
8699                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
8700                        updateLruProcessLocked(cpr.proc, false, null);
8701                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
8702                    }
8703                }
8704
8705                if (cpr.proc != null) {
8706                    if (false) {
8707                        if (cpr.name.flattenToShortString().equals(
8708                                "com.android.providers.calendar/.CalendarProvider2")) {
8709                            Slog.v(TAG, "****************** KILLING "
8710                                + cpr.name.flattenToShortString());
8711                            Process.killProcess(cpr.proc.pid);
8712                        }
8713                    }
8714                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
8715                    boolean success = updateOomAdjLocked(cpr.proc);
8716                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
8717                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
8718                    // NOTE: there is still a race here where a signal could be
8719                    // pending on the process even though we managed to update its
8720                    // adj level.  Not sure what to do about this, but at least
8721                    // the race is now smaller.
8722                    if (!success) {
8723                        // Uh oh...  it looks like the provider's process
8724                        // has been killed on us.  We need to wait for a new
8725                        // process to be started, and make sure its death
8726                        // doesn't kill our process.
8727                        Slog.i(TAG,
8728                                "Existing provider " + cpr.name.flattenToShortString()
8729                                + " is crashing; detaching " + r);
8730                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
8731                        checkTime(startTime, "getContentProviderImpl: before appDied");
8732                        appDiedLocked(cpr.proc);
8733                        checkTime(startTime, "getContentProviderImpl: after appDied");
8734                        if (!lastRef) {
8735                            // This wasn't the last ref our process had on
8736                            // the provider...  we have now been killed, bail.
8737                            return null;
8738                        }
8739                        providerRunning = false;
8740                        conn = null;
8741                    }
8742                }
8743
8744                Binder.restoreCallingIdentity(origId);
8745            }
8746
8747            boolean singleton;
8748            if (!providerRunning) {
8749                try {
8750                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
8751                    cpi = AppGlobals.getPackageManager().
8752                        resolveContentProvider(name,
8753                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
8754                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
8755                } catch (RemoteException ex) {
8756                }
8757                if (cpi == null) {
8758                    return null;
8759                }
8760                // If the provider is a singleton AND
8761                // (it's a call within the same user || the provider is a
8762                // privileged app)
8763                // Then allow connecting to the singleton provider
8764                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8765                        cpi.name, cpi.flags)
8766                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
8767                if (singleton) {
8768                    userId = UserHandle.USER_OWNER;
8769                }
8770                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
8771                checkTime(startTime, "getContentProviderImpl: got app info for user");
8772
8773                String msg;
8774                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
8775                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
8776                        != null) {
8777                    throw new SecurityException(msg);
8778                }
8779                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
8780
8781                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
8782                        && !cpi.processName.equals("system")) {
8783                    // If this content provider does not run in the system
8784                    // process, and the system is not yet ready to run other
8785                    // processes, then fail fast instead of hanging.
8786                    throw new IllegalArgumentException(
8787                            "Attempt to launch content provider before system ready");
8788                }
8789
8790                // Make sure that the user who owns this provider is running.  If not,
8791                // we don't want to allow it to run.
8792                if (!isUserRunningLocked(userId, false)) {
8793                    Slog.w(TAG, "Unable to launch app "
8794                            + cpi.applicationInfo.packageName + "/"
8795                            + cpi.applicationInfo.uid + " for provider "
8796                            + name + ": user " + userId + " is stopped");
8797                    return null;
8798                }
8799
8800                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8801                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
8802                cpr = mProviderMap.getProviderByClass(comp, userId);
8803                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
8804                final boolean firstClass = cpr == null;
8805                if (firstClass) {
8806                    final long ident = Binder.clearCallingIdentity();
8807                    try {
8808                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
8809                        ApplicationInfo ai =
8810                            AppGlobals.getPackageManager().
8811                                getApplicationInfo(
8812                                        cpi.applicationInfo.packageName,
8813                                        STOCK_PM_FLAGS, userId);
8814                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
8815                        if (ai == null) {
8816                            Slog.w(TAG, "No package info for content provider "
8817                                    + cpi.name);
8818                            return null;
8819                        }
8820                        ai = getAppInfoForUser(ai, userId);
8821                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
8822                    } catch (RemoteException ex) {
8823                        // pm is in same process, this will never happen.
8824                    } finally {
8825                        Binder.restoreCallingIdentity(ident);
8826                    }
8827                }
8828
8829                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
8830
8831                if (r != null && cpr.canRunHere(r)) {
8832                    // If this is a multiprocess provider, then just return its
8833                    // info and allow the caller to instantiate it.  Only do
8834                    // this if the provider is the same user as the caller's
8835                    // process, or can run as root (so can be in any process).
8836                    return cpr.newHolder(null);
8837                }
8838
8839                if (DEBUG_PROVIDER) {
8840                    RuntimeException e = new RuntimeException("here");
8841                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
8842                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
8843                }
8844
8845                // This is single process, and our app is now connecting to it.
8846                // See if we are already in the process of launching this
8847                // provider.
8848                final int N = mLaunchingProviders.size();
8849                int i;
8850                for (i=0; i<N; i++) {
8851                    if (mLaunchingProviders.get(i) == cpr) {
8852                        break;
8853                    }
8854                }
8855
8856                // If the provider is not already being launched, then get it
8857                // started.
8858                if (i >= N) {
8859                    final long origId = Binder.clearCallingIdentity();
8860
8861                    try {
8862                        // Content provider is now in use, its package can't be stopped.
8863                        try {
8864                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
8865                            AppGlobals.getPackageManager().setPackageStoppedState(
8866                                    cpr.appInfo.packageName, false, userId);
8867                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
8868                        } catch (RemoteException e) {
8869                        } catch (IllegalArgumentException e) {
8870                            Slog.w(TAG, "Failed trying to unstop package "
8871                                    + cpr.appInfo.packageName + ": " + e);
8872                        }
8873
8874                        // Use existing process if already started
8875                        checkTime(startTime, "getContentProviderImpl: looking for process record");
8876                        ProcessRecord proc = getProcessRecordLocked(
8877                                cpi.processName, cpr.appInfo.uid, false);
8878                        if (proc != null && proc.thread != null) {
8879                            if (DEBUG_PROVIDER) {
8880                                Slog.d(TAG, "Installing in existing process " + proc);
8881                            }
8882                            if (!proc.pubProviders.containsKey(cpi.name)) {
8883                                checkTime(startTime, "getContentProviderImpl: scheduling install");
8884                                proc.pubProviders.put(cpi.name, cpr);
8885                                try {
8886                                    proc.thread.scheduleInstallProvider(cpi);
8887                                } catch (RemoteException e) {
8888                                }
8889                            }
8890                        } else {
8891                            checkTime(startTime, "getContentProviderImpl: before start process");
8892                            proc = startProcessLocked(cpi.processName,
8893                                    cpr.appInfo, false, 0, "content provider",
8894                                    new ComponentName(cpi.applicationInfo.packageName,
8895                                            cpi.name), false, false, false);
8896                            checkTime(startTime, "getContentProviderImpl: after start process");
8897                            if (proc == null) {
8898                                Slog.w(TAG, "Unable to launch app "
8899                                        + cpi.applicationInfo.packageName + "/"
8900                                        + cpi.applicationInfo.uid + " for provider "
8901                                        + name + ": process is bad");
8902                                return null;
8903                            }
8904                        }
8905                        cpr.launchingApp = proc;
8906                        mLaunchingProviders.add(cpr);
8907                    } finally {
8908                        Binder.restoreCallingIdentity(origId);
8909                    }
8910                }
8911
8912                checkTime(startTime, "getContentProviderImpl: updating data structures");
8913
8914                // Make sure the provider is published (the same provider class
8915                // may be published under multiple names).
8916                if (firstClass) {
8917                    mProviderMap.putProviderByClass(comp, cpr);
8918                }
8919
8920                mProviderMap.putProviderByName(name, cpr);
8921                conn = incProviderCountLocked(r, cpr, token, stable);
8922                if (conn != null) {
8923                    conn.waiting = true;
8924                }
8925            }
8926            checkTime(startTime, "getContentProviderImpl: done!");
8927        }
8928
8929        // Wait for the provider to be published...
8930        synchronized (cpr) {
8931            while (cpr.provider == null) {
8932                if (cpr.launchingApp == null) {
8933                    Slog.w(TAG, "Unable to launch app "
8934                            + cpi.applicationInfo.packageName + "/"
8935                            + cpi.applicationInfo.uid + " for provider "
8936                            + name + ": launching app became null");
8937                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
8938                            UserHandle.getUserId(cpi.applicationInfo.uid),
8939                            cpi.applicationInfo.packageName,
8940                            cpi.applicationInfo.uid, name);
8941                    return null;
8942                }
8943                try {
8944                    if (DEBUG_MU) {
8945                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
8946                                + cpr.launchingApp);
8947                    }
8948                    if (conn != null) {
8949                        conn.waiting = true;
8950                    }
8951                    cpr.wait();
8952                } catch (InterruptedException ex) {
8953                } finally {
8954                    if (conn != null) {
8955                        conn.waiting = false;
8956                    }
8957                }
8958            }
8959        }
8960        return cpr != null ? cpr.newHolder(conn) : null;
8961    }
8962
8963    @Override
8964    public final ContentProviderHolder getContentProvider(
8965            IApplicationThread caller, String name, int userId, boolean stable) {
8966        enforceNotIsolatedCaller("getContentProvider");
8967        if (caller == null) {
8968            String msg = "null IApplicationThread when getting content provider "
8969                    + name;
8970            Slog.w(TAG, msg);
8971            throw new SecurityException(msg);
8972        }
8973        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
8974        // with cross-user grant.
8975        return getContentProviderImpl(caller, name, null, stable, userId);
8976    }
8977
8978    public ContentProviderHolder getContentProviderExternal(
8979            String name, int userId, IBinder token) {
8980        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8981            "Do not have permission in call getContentProviderExternal()");
8982        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
8983                false, ALLOW_FULL_ONLY, "getContentProvider", null);
8984        return getContentProviderExternalUnchecked(name, token, userId);
8985    }
8986
8987    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
8988            IBinder token, int userId) {
8989        return getContentProviderImpl(null, name, token, true, userId);
8990    }
8991
8992    /**
8993     * Drop a content provider from a ProcessRecord's bookkeeping
8994     */
8995    public void removeContentProvider(IBinder connection, boolean stable) {
8996        enforceNotIsolatedCaller("removeContentProvider");
8997        long ident = Binder.clearCallingIdentity();
8998        try {
8999            synchronized (this) {
9000                ContentProviderConnection conn;
9001                try {
9002                    conn = (ContentProviderConnection)connection;
9003                } catch (ClassCastException e) {
9004                    String msg ="removeContentProvider: " + connection
9005                            + " not a ContentProviderConnection";
9006                    Slog.w(TAG, msg);
9007                    throw new IllegalArgumentException(msg);
9008                }
9009                if (conn == null) {
9010                    throw new NullPointerException("connection is null");
9011                }
9012                if (decProviderCountLocked(conn, null, null, stable)) {
9013                    updateOomAdjLocked();
9014                }
9015            }
9016        } finally {
9017            Binder.restoreCallingIdentity(ident);
9018        }
9019    }
9020
9021    public void removeContentProviderExternal(String name, IBinder token) {
9022        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9023            "Do not have permission in call removeContentProviderExternal()");
9024        int userId = UserHandle.getCallingUserId();
9025        long ident = Binder.clearCallingIdentity();
9026        try {
9027            removeContentProviderExternalUnchecked(name, token, userId);
9028        } finally {
9029            Binder.restoreCallingIdentity(ident);
9030        }
9031    }
9032
9033    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
9034        synchronized (this) {
9035            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
9036            if(cpr == null) {
9037                //remove from mProvidersByClass
9038                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
9039                return;
9040            }
9041
9042            //update content provider record entry info
9043            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
9044            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
9045            if (localCpr.hasExternalProcessHandles()) {
9046                if (localCpr.removeExternalProcessHandleLocked(token)) {
9047                    updateOomAdjLocked();
9048                } else {
9049                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
9050                            + " with no external reference for token: "
9051                            + token + ".");
9052                }
9053            } else {
9054                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
9055                        + " with no external references.");
9056            }
9057        }
9058    }
9059
9060    public final void publishContentProviders(IApplicationThread caller,
9061            List<ContentProviderHolder> providers) {
9062        if (providers == null) {
9063            return;
9064        }
9065
9066        enforceNotIsolatedCaller("publishContentProviders");
9067        synchronized (this) {
9068            final ProcessRecord r = getRecordForAppLocked(caller);
9069            if (DEBUG_MU)
9070                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
9071            if (r == null) {
9072                throw new SecurityException(
9073                        "Unable to find app for caller " + caller
9074                      + " (pid=" + Binder.getCallingPid()
9075                      + ") when publishing content providers");
9076            }
9077
9078            final long origId = Binder.clearCallingIdentity();
9079
9080            final int N = providers.size();
9081            for (int i=0; i<N; i++) {
9082                ContentProviderHolder src = providers.get(i);
9083                if (src == null || src.info == null || src.provider == null) {
9084                    continue;
9085                }
9086                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
9087                if (DEBUG_MU)
9088                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
9089                if (dst != null) {
9090                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
9091                    mProviderMap.putProviderByClass(comp, dst);
9092                    String names[] = dst.info.authority.split(";");
9093                    for (int j = 0; j < names.length; j++) {
9094                        mProviderMap.putProviderByName(names[j], dst);
9095                    }
9096
9097                    int NL = mLaunchingProviders.size();
9098                    int j;
9099                    for (j=0; j<NL; j++) {
9100                        if (mLaunchingProviders.get(j) == dst) {
9101                            mLaunchingProviders.remove(j);
9102                            j--;
9103                            NL--;
9104                        }
9105                    }
9106                    synchronized (dst) {
9107                        dst.provider = src.provider;
9108                        dst.proc = r;
9109                        dst.notifyAll();
9110                    }
9111                    updateOomAdjLocked(r);
9112                }
9113            }
9114
9115            Binder.restoreCallingIdentity(origId);
9116        }
9117    }
9118
9119    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
9120        ContentProviderConnection conn;
9121        try {
9122            conn = (ContentProviderConnection)connection;
9123        } catch (ClassCastException e) {
9124            String msg ="refContentProvider: " + connection
9125                    + " not a ContentProviderConnection";
9126            Slog.w(TAG, msg);
9127            throw new IllegalArgumentException(msg);
9128        }
9129        if (conn == null) {
9130            throw new NullPointerException("connection is null");
9131        }
9132
9133        synchronized (this) {
9134            if (stable > 0) {
9135                conn.numStableIncs += stable;
9136            }
9137            stable = conn.stableCount + stable;
9138            if (stable < 0) {
9139                throw new IllegalStateException("stableCount < 0: " + stable);
9140            }
9141
9142            if (unstable > 0) {
9143                conn.numUnstableIncs += unstable;
9144            }
9145            unstable = conn.unstableCount + unstable;
9146            if (unstable < 0) {
9147                throw new IllegalStateException("unstableCount < 0: " + unstable);
9148            }
9149
9150            if ((stable+unstable) <= 0) {
9151                throw new IllegalStateException("ref counts can't go to zero here: stable="
9152                        + stable + " unstable=" + unstable);
9153            }
9154            conn.stableCount = stable;
9155            conn.unstableCount = unstable;
9156            return !conn.dead;
9157        }
9158    }
9159
9160    public void unstableProviderDied(IBinder connection) {
9161        ContentProviderConnection conn;
9162        try {
9163            conn = (ContentProviderConnection)connection;
9164        } catch (ClassCastException e) {
9165            String msg ="refContentProvider: " + connection
9166                    + " not a ContentProviderConnection";
9167            Slog.w(TAG, msg);
9168            throw new IllegalArgumentException(msg);
9169        }
9170        if (conn == null) {
9171            throw new NullPointerException("connection is null");
9172        }
9173
9174        // Safely retrieve the content provider associated with the connection.
9175        IContentProvider provider;
9176        synchronized (this) {
9177            provider = conn.provider.provider;
9178        }
9179
9180        if (provider == null) {
9181            // Um, yeah, we're way ahead of you.
9182            return;
9183        }
9184
9185        // Make sure the caller is being honest with us.
9186        if (provider.asBinder().pingBinder()) {
9187            // Er, no, still looks good to us.
9188            synchronized (this) {
9189                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
9190                        + " says " + conn + " died, but we don't agree");
9191                return;
9192            }
9193        }
9194
9195        // Well look at that!  It's dead!
9196        synchronized (this) {
9197            if (conn.provider.provider != provider) {
9198                // But something changed...  good enough.
9199                return;
9200            }
9201
9202            ProcessRecord proc = conn.provider.proc;
9203            if (proc == null || proc.thread == null) {
9204                // Seems like the process is already cleaned up.
9205                return;
9206            }
9207
9208            // As far as we're concerned, this is just like receiving a
9209            // death notification...  just a bit prematurely.
9210            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
9211                    + ") early provider death");
9212            final long ident = Binder.clearCallingIdentity();
9213            try {
9214                appDiedLocked(proc);
9215            } finally {
9216                Binder.restoreCallingIdentity(ident);
9217            }
9218        }
9219    }
9220
9221    @Override
9222    public void appNotRespondingViaProvider(IBinder connection) {
9223        enforceCallingPermission(
9224                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
9225
9226        final ContentProviderConnection conn = (ContentProviderConnection) connection;
9227        if (conn == null) {
9228            Slog.w(TAG, "ContentProviderConnection is null");
9229            return;
9230        }
9231
9232        final ProcessRecord host = conn.provider.proc;
9233        if (host == null) {
9234            Slog.w(TAG, "Failed to find hosting ProcessRecord");
9235            return;
9236        }
9237
9238        final long token = Binder.clearCallingIdentity();
9239        try {
9240            appNotResponding(host, null, null, false, "ContentProvider not responding");
9241        } finally {
9242            Binder.restoreCallingIdentity(token);
9243        }
9244    }
9245
9246    public final void installSystemProviders() {
9247        List<ProviderInfo> providers;
9248        synchronized (this) {
9249            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
9250            providers = generateApplicationProvidersLocked(app);
9251            if (providers != null) {
9252                for (int i=providers.size()-1; i>=0; i--) {
9253                    ProviderInfo pi = (ProviderInfo)providers.get(i);
9254                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
9255                        Slog.w(TAG, "Not installing system proc provider " + pi.name
9256                                + ": not system .apk");
9257                        providers.remove(i);
9258                    }
9259                }
9260            }
9261        }
9262        if (providers != null) {
9263            mSystemThread.installSystemProviders(providers);
9264        }
9265
9266        mCoreSettingsObserver = new CoreSettingsObserver(this);
9267
9268        //mUsageStatsService.monitorPackages();
9269    }
9270
9271    /**
9272     * Allows apps to retrieve the MIME type of a URI.
9273     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
9274     * users, then it does not need permission to access the ContentProvider.
9275     * Either, it needs cross-user uri grants.
9276     *
9277     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
9278     *
9279     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
9280     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
9281     */
9282    public String getProviderMimeType(Uri uri, int userId) {
9283        enforceNotIsolatedCaller("getProviderMimeType");
9284        final String name = uri.getAuthority();
9285        int callingUid = Binder.getCallingUid();
9286        int callingPid = Binder.getCallingPid();
9287        long ident = 0;
9288        boolean clearedIdentity = false;
9289        userId = unsafeConvertIncomingUser(userId);
9290        if (canClearIdentity(callingPid, callingUid, userId)) {
9291            clearedIdentity = true;
9292            ident = Binder.clearCallingIdentity();
9293        }
9294        ContentProviderHolder holder = null;
9295        try {
9296            holder = getContentProviderExternalUnchecked(name, null, userId);
9297            if (holder != null) {
9298                return holder.provider.getType(uri);
9299            }
9300        } catch (RemoteException e) {
9301            Log.w(TAG, "Content provider dead retrieving " + uri, e);
9302            return null;
9303        } finally {
9304            // We need to clear the identity to call removeContentProviderExternalUnchecked
9305            if (!clearedIdentity) {
9306                ident = Binder.clearCallingIdentity();
9307            }
9308            try {
9309                if (holder != null) {
9310                    removeContentProviderExternalUnchecked(name, null, userId);
9311                }
9312            } finally {
9313                Binder.restoreCallingIdentity(ident);
9314            }
9315        }
9316
9317        return null;
9318    }
9319
9320    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
9321        if (UserHandle.getUserId(callingUid) == userId) {
9322            return true;
9323        }
9324        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
9325                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
9326                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
9327                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
9328                return true;
9329        }
9330        return false;
9331    }
9332
9333    // =========================================================
9334    // GLOBAL MANAGEMENT
9335    // =========================================================
9336
9337    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
9338            boolean isolated, int isolatedUid) {
9339        String proc = customProcess != null ? customProcess : info.processName;
9340        BatteryStatsImpl.Uid.Proc ps = null;
9341        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9342        int uid = info.uid;
9343        if (isolated) {
9344            if (isolatedUid == 0) {
9345                int userId = UserHandle.getUserId(uid);
9346                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
9347                while (true) {
9348                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
9349                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
9350                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
9351                    }
9352                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
9353                    mNextIsolatedProcessUid++;
9354                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
9355                        // No process for this uid, use it.
9356                        break;
9357                    }
9358                    stepsLeft--;
9359                    if (stepsLeft <= 0) {
9360                        return null;
9361                    }
9362                }
9363            } else {
9364                // Special case for startIsolatedProcess (internal only), where
9365                // the uid of the isolated process is specified by the caller.
9366                uid = isolatedUid;
9367            }
9368        }
9369        return new ProcessRecord(stats, info, proc, uid);
9370    }
9371
9372    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
9373            String abiOverride) {
9374        ProcessRecord app;
9375        if (!isolated) {
9376            app = getProcessRecordLocked(info.processName, info.uid, true);
9377        } else {
9378            app = null;
9379        }
9380
9381        if (app == null) {
9382            app = newProcessRecordLocked(info, null, isolated, 0);
9383            mProcessNames.put(info.processName, app.uid, app);
9384            if (isolated) {
9385                mIsolatedProcesses.put(app.uid, app);
9386            }
9387            updateLruProcessLocked(app, false, null);
9388            updateOomAdjLocked();
9389        }
9390
9391        // This package really, really can not be stopped.
9392        try {
9393            AppGlobals.getPackageManager().setPackageStoppedState(
9394                    info.packageName, false, UserHandle.getUserId(app.uid));
9395        } catch (RemoteException e) {
9396        } catch (IllegalArgumentException e) {
9397            Slog.w(TAG, "Failed trying to unstop package "
9398                    + info.packageName + ": " + e);
9399        }
9400
9401        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
9402                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
9403            app.persistent = true;
9404            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
9405        }
9406        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
9407            mPersistentStartingProcesses.add(app);
9408            startProcessLocked(app, "added application", app.processName, abiOverride,
9409                    null /* entryPoint */, null /* entryPointArgs */);
9410        }
9411
9412        return app;
9413    }
9414
9415    public void unhandledBack() {
9416        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
9417                "unhandledBack()");
9418
9419        synchronized(this) {
9420            final long origId = Binder.clearCallingIdentity();
9421            try {
9422                getFocusedStack().unhandledBackLocked();
9423            } finally {
9424                Binder.restoreCallingIdentity(origId);
9425            }
9426        }
9427    }
9428
9429    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
9430        enforceNotIsolatedCaller("openContentUri");
9431        final int userId = UserHandle.getCallingUserId();
9432        String name = uri.getAuthority();
9433        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
9434        ParcelFileDescriptor pfd = null;
9435        if (cph != null) {
9436            // We record the binder invoker's uid in thread-local storage before
9437            // going to the content provider to open the file.  Later, in the code
9438            // that handles all permissions checks, we look for this uid and use
9439            // that rather than the Activity Manager's own uid.  The effect is that
9440            // we do the check against the caller's permissions even though it looks
9441            // to the content provider like the Activity Manager itself is making
9442            // the request.
9443            Binder token = new Binder();
9444            sCallerIdentity.set(new Identity(
9445                    token, Binder.getCallingPid(), Binder.getCallingUid()));
9446            try {
9447                pfd = cph.provider.openFile(null, uri, "r", null, token);
9448            } catch (FileNotFoundException e) {
9449                // do nothing; pfd will be returned null
9450            } finally {
9451                // Ensure that whatever happens, we clean up the identity state
9452                sCallerIdentity.remove();
9453                // Ensure we're done with the provider.
9454                removeContentProviderExternalUnchecked(name, null, userId);
9455            }
9456        } else {
9457            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
9458        }
9459        return pfd;
9460    }
9461
9462    // Actually is sleeping or shutting down or whatever else in the future
9463    // is an inactive state.
9464    public boolean isSleepingOrShuttingDown() {
9465        return isSleeping() || mShuttingDown;
9466    }
9467
9468    public boolean isSleeping() {
9469        return mSleeping;
9470    }
9471
9472    void onWakefulnessChanged(int wakefulness) {
9473        synchronized(this) {
9474            mWakefulness = wakefulness;
9475            updateSleepIfNeededLocked();
9476        }
9477    }
9478
9479    void finishRunningVoiceLocked() {
9480        if (mRunningVoice) {
9481            mRunningVoice = false;
9482            updateSleepIfNeededLocked();
9483        }
9484    }
9485
9486    void updateSleepIfNeededLocked() {
9487        if (mSleeping && !shouldSleepLocked()) {
9488            mSleeping = false;
9489            mStackSupervisor.comeOutOfSleepIfNeededLocked();
9490        } else if (!mSleeping && shouldSleepLocked()) {
9491            mSleeping = true;
9492            mStackSupervisor.goingToSleepLocked();
9493
9494            // Initialize the wake times of all processes.
9495            checkExcessivePowerUsageLocked(false);
9496            mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9497            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9498            mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
9499        }
9500    }
9501
9502    private boolean shouldSleepLocked() {
9503        // Resume applications while running a voice interactor.
9504        if (mRunningVoice) {
9505            return false;
9506        }
9507
9508        switch (mWakefulness) {
9509            case PowerManagerInternal.WAKEFULNESS_AWAKE:
9510            case PowerManagerInternal.WAKEFULNESS_DREAMING:
9511                // If we're interactive but applications are already paused then defer
9512                // resuming them until the lock screen is hidden.
9513                return mSleeping && mLockScreenShown != LOCK_SCREEN_HIDDEN;
9514            case PowerManagerInternal.WAKEFULNESS_DOZING:
9515                // If we're dozing then pause applications whenever the lock screen is shown.
9516                return mLockScreenShown != LOCK_SCREEN_HIDDEN;
9517            case PowerManagerInternal.WAKEFULNESS_ASLEEP:
9518            default:
9519                // If we're asleep then pause applications unconditionally.
9520                return true;
9521        }
9522    }
9523
9524    /** Pokes the task persister. */
9525    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
9526        if (task != null && task.stack != null && task.stack.isHomeStack()) {
9527            // Never persist the home stack.
9528            return;
9529        }
9530        mTaskPersister.wakeup(task, flush);
9531    }
9532
9533    /** Notifies all listeners when the task stack has changed. */
9534    void notifyTaskStackChangedLocked() {
9535        mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
9536        Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
9537        mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
9538    }
9539
9540    @Override
9541    public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
9542        mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
9543    }
9544
9545    @Override
9546    public boolean shutdown(int timeout) {
9547        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
9548                != PackageManager.PERMISSION_GRANTED) {
9549            throw new SecurityException("Requires permission "
9550                    + android.Manifest.permission.SHUTDOWN);
9551        }
9552
9553        boolean timedout = false;
9554
9555        synchronized(this) {
9556            mShuttingDown = true;
9557            updateEventDispatchingLocked();
9558            timedout = mStackSupervisor.shutdownLocked(timeout);
9559        }
9560
9561        mAppOpsService.shutdown();
9562        if (mUsageStatsService != null) {
9563            mUsageStatsService.prepareShutdown();
9564        }
9565        mBatteryStatsService.shutdown();
9566        synchronized (this) {
9567            mProcessStats.shutdownLocked();
9568            notifyTaskPersisterLocked(null, true);
9569        }
9570
9571        return timedout;
9572    }
9573
9574    public final void activitySlept(IBinder token) {
9575        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
9576
9577        final long origId = Binder.clearCallingIdentity();
9578
9579        synchronized (this) {
9580            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9581            if (r != null) {
9582                mStackSupervisor.activitySleptLocked(r);
9583            }
9584        }
9585
9586        Binder.restoreCallingIdentity(origId);
9587    }
9588
9589    private String lockScreenShownToString() {
9590        switch (mLockScreenShown) {
9591            case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
9592            case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
9593            case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
9594            default: return "Unknown=" + mLockScreenShown;
9595        }
9596    }
9597
9598    void logLockScreen(String msg) {
9599        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg
9600                + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
9601                + PowerManagerInternal.wakefulnessToString(mWakefulness)
9602                + " mSleeping=" + mSleeping);
9603    }
9604
9605    void startRunningVoiceLocked() {
9606        if (!mRunningVoice) {
9607            mRunningVoice = true;
9608            updateSleepIfNeededLocked();
9609        }
9610    }
9611
9612    private void updateEventDispatchingLocked() {
9613        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
9614    }
9615
9616    public void setLockScreenShown(boolean shown) {
9617        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
9618                != PackageManager.PERMISSION_GRANTED) {
9619            throw new SecurityException("Requires permission "
9620                    + android.Manifest.permission.DEVICE_POWER);
9621        }
9622
9623        synchronized(this) {
9624            long ident = Binder.clearCallingIdentity();
9625            try {
9626                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
9627                mLockScreenShown = shown ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
9628                updateSleepIfNeededLocked();
9629            } finally {
9630                Binder.restoreCallingIdentity(ident);
9631            }
9632        }
9633    }
9634
9635    @Override
9636    public void stopAppSwitches() {
9637        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
9638                != PackageManager.PERMISSION_GRANTED) {
9639            throw new SecurityException("Requires permission "
9640                    + android.Manifest.permission.STOP_APP_SWITCHES);
9641        }
9642
9643        synchronized(this) {
9644            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
9645                    + APP_SWITCH_DELAY_TIME;
9646            mDidAppSwitch = false;
9647            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
9648            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
9649            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
9650        }
9651    }
9652
9653    public void resumeAppSwitches() {
9654        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
9655                != PackageManager.PERMISSION_GRANTED) {
9656            throw new SecurityException("Requires permission "
9657                    + android.Manifest.permission.STOP_APP_SWITCHES);
9658        }
9659
9660        synchronized(this) {
9661            // Note that we don't execute any pending app switches... we will
9662            // let those wait until either the timeout, or the next start
9663            // activity request.
9664            mAppSwitchesAllowedTime = 0;
9665        }
9666    }
9667
9668    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
9669            int callingPid, int callingUid, String name) {
9670        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
9671            return true;
9672        }
9673
9674        int perm = checkComponentPermission(
9675                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
9676                sourceUid, -1, true);
9677        if (perm == PackageManager.PERMISSION_GRANTED) {
9678            return true;
9679        }
9680
9681        // If the actual IPC caller is different from the logical source, then
9682        // also see if they are allowed to control app switches.
9683        if (callingUid != -1 && callingUid != sourceUid) {
9684            perm = checkComponentPermission(
9685                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
9686                    callingUid, -1, true);
9687            if (perm == PackageManager.PERMISSION_GRANTED) {
9688                return true;
9689            }
9690        }
9691
9692        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
9693        return false;
9694    }
9695
9696    public void setDebugApp(String packageName, boolean waitForDebugger,
9697            boolean persistent) {
9698        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
9699                "setDebugApp()");
9700
9701        long ident = Binder.clearCallingIdentity();
9702        try {
9703            // Note that this is not really thread safe if there are multiple
9704            // callers into it at the same time, but that's not a situation we
9705            // care about.
9706            if (persistent) {
9707                final ContentResolver resolver = mContext.getContentResolver();
9708                Settings.Global.putString(
9709                    resolver, Settings.Global.DEBUG_APP,
9710                    packageName);
9711                Settings.Global.putInt(
9712                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
9713                    waitForDebugger ? 1 : 0);
9714            }
9715
9716            synchronized (this) {
9717                if (!persistent) {
9718                    mOrigDebugApp = mDebugApp;
9719                    mOrigWaitForDebugger = mWaitForDebugger;
9720                }
9721                mDebugApp = packageName;
9722                mWaitForDebugger = waitForDebugger;
9723                mDebugTransient = !persistent;
9724                if (packageName != null) {
9725                    forceStopPackageLocked(packageName, -1, false, false, true, true,
9726                            false, UserHandle.USER_ALL, "set debug app");
9727                }
9728            }
9729        } finally {
9730            Binder.restoreCallingIdentity(ident);
9731        }
9732    }
9733
9734    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
9735        synchronized (this) {
9736            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
9737            if (!isDebuggable) {
9738                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
9739                    throw new SecurityException("Process not debuggable: " + app.packageName);
9740                }
9741            }
9742
9743            mOpenGlTraceApp = processName;
9744        }
9745    }
9746
9747    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
9748        synchronized (this) {
9749            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
9750            if (!isDebuggable) {
9751                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
9752                    throw new SecurityException("Process not debuggable: " + app.packageName);
9753                }
9754            }
9755            mProfileApp = processName;
9756            mProfileFile = profilerInfo.profileFile;
9757            if (mProfileFd != null) {
9758                try {
9759                    mProfileFd.close();
9760                } catch (IOException e) {
9761                }
9762                mProfileFd = null;
9763            }
9764            mProfileFd = profilerInfo.profileFd;
9765            mSamplingInterval = profilerInfo.samplingInterval;
9766            mAutoStopProfiler = profilerInfo.autoStopProfiler;
9767            mProfileType = 0;
9768        }
9769    }
9770
9771    @Override
9772    public void setAlwaysFinish(boolean enabled) {
9773        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
9774                "setAlwaysFinish()");
9775
9776        Settings.Global.putInt(
9777                mContext.getContentResolver(),
9778                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
9779
9780        synchronized (this) {
9781            mAlwaysFinishActivities = enabled;
9782        }
9783    }
9784
9785    @Override
9786    public void setActivityController(IActivityController controller) {
9787        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
9788                "setActivityController()");
9789        synchronized (this) {
9790            mController = controller;
9791            Watchdog.getInstance().setActivityController(controller);
9792        }
9793    }
9794
9795    @Override
9796    public void setUserIsMonkey(boolean userIsMonkey) {
9797        synchronized (this) {
9798            synchronized (mPidsSelfLocked) {
9799                final int callingPid = Binder.getCallingPid();
9800                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
9801                if (precessRecord == null) {
9802                    throw new SecurityException("Unknown process: " + callingPid);
9803                }
9804                if (precessRecord.instrumentationUiAutomationConnection  == null) {
9805                    throw new SecurityException("Only an instrumentation process "
9806                            + "with a UiAutomation can call setUserIsMonkey");
9807                }
9808            }
9809            mUserIsMonkey = userIsMonkey;
9810        }
9811    }
9812
9813    @Override
9814    public boolean isUserAMonkey() {
9815        synchronized (this) {
9816            // If there is a controller also implies the user is a monkey.
9817            return (mUserIsMonkey || mController != null);
9818        }
9819    }
9820
9821    public void requestBugReport() {
9822        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
9823        SystemProperties.set("ctl.start", "bugreport");
9824    }
9825
9826    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
9827        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
9828    }
9829
9830    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
9831        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
9832            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
9833        }
9834        return KEY_DISPATCHING_TIMEOUT;
9835    }
9836
9837    @Override
9838    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
9839        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
9840                != PackageManager.PERMISSION_GRANTED) {
9841            throw new SecurityException("Requires permission "
9842                    + android.Manifest.permission.FILTER_EVENTS);
9843        }
9844        ProcessRecord proc;
9845        long timeout;
9846        synchronized (this) {
9847            synchronized (mPidsSelfLocked) {
9848                proc = mPidsSelfLocked.get(pid);
9849            }
9850            timeout = getInputDispatchingTimeoutLocked(proc);
9851        }
9852
9853        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
9854            return -1;
9855        }
9856
9857        return timeout;
9858    }
9859
9860    /**
9861     * Handle input dispatching timeouts.
9862     * Returns whether input dispatching should be aborted or not.
9863     */
9864    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
9865            final ActivityRecord activity, final ActivityRecord parent,
9866            final boolean aboveSystem, String reason) {
9867        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
9868                != PackageManager.PERMISSION_GRANTED) {
9869            throw new SecurityException("Requires permission "
9870                    + android.Manifest.permission.FILTER_EVENTS);
9871        }
9872
9873        final String annotation;
9874        if (reason == null) {
9875            annotation = "Input dispatching timed out";
9876        } else {
9877            annotation = "Input dispatching timed out (" + reason + ")";
9878        }
9879
9880        if (proc != null) {
9881            synchronized (this) {
9882                if (proc.debugging) {
9883                    return false;
9884                }
9885
9886                if (mDidDexOpt) {
9887                    // Give more time since we were dexopting.
9888                    mDidDexOpt = false;
9889                    return false;
9890                }
9891
9892                if (proc.instrumentationClass != null) {
9893                    Bundle info = new Bundle();
9894                    info.putString("shortMsg", "keyDispatchingTimedOut");
9895                    info.putString("longMsg", annotation);
9896                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
9897                    return true;
9898                }
9899            }
9900            mHandler.post(new Runnable() {
9901                @Override
9902                public void run() {
9903                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
9904                }
9905            });
9906        }
9907
9908        return true;
9909    }
9910
9911    public Bundle getAssistContextExtras(int requestType) {
9912        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null,
9913                UserHandle.getCallingUserId());
9914        if (pae == null) {
9915            return null;
9916        }
9917        synchronized (pae) {
9918            while (!pae.haveResult) {
9919                try {
9920                    pae.wait();
9921                } catch (InterruptedException e) {
9922                }
9923            }
9924            if (pae.result != null) {
9925                pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
9926            }
9927        }
9928        synchronized (this) {
9929            mPendingAssistExtras.remove(pae);
9930            mHandler.removeCallbacks(pae);
9931        }
9932        return pae.extras;
9933    }
9934
9935    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
9936            int userHandle) {
9937        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
9938                "getAssistContextExtras()");
9939        PendingAssistExtras pae;
9940        Bundle extras = new Bundle();
9941        synchronized (this) {
9942            ActivityRecord activity = getFocusedStack().mResumedActivity;
9943            if (activity == null) {
9944                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
9945                return null;
9946            }
9947            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
9948            if (activity.app == null || activity.app.thread == null) {
9949                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
9950                return null;
9951            }
9952            if (activity.app.pid == Binder.getCallingPid()) {
9953                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
9954                return null;
9955            }
9956            pae = new PendingAssistExtras(activity, extras, intent, hint, userHandle);
9957            try {
9958                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
9959                        requestType);
9960                mPendingAssistExtras.add(pae);
9961                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
9962            } catch (RemoteException e) {
9963                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
9964                return null;
9965            }
9966            return pae;
9967        }
9968    }
9969
9970    public void reportAssistContextExtras(IBinder token, Bundle extras) {
9971        PendingAssistExtras pae = (PendingAssistExtras)token;
9972        synchronized (pae) {
9973            pae.result = extras;
9974            pae.haveResult = true;
9975            pae.notifyAll();
9976            if (pae.intent == null) {
9977                // Caller is just waiting for the result.
9978                return;
9979            }
9980        }
9981
9982        // We are now ready to launch the assist activity.
9983        synchronized (this) {
9984            boolean exists = mPendingAssistExtras.remove(pae);
9985            mHandler.removeCallbacks(pae);
9986            if (!exists) {
9987                // Timed out.
9988                return;
9989            }
9990        }
9991        pae.intent.replaceExtras(extras);
9992        if (pae.hint != null) {
9993            pae.intent.putExtra(pae.hint, true);
9994        }
9995        pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
9996                | Intent.FLAG_ACTIVITY_SINGLE_TOP
9997                | Intent.FLAG_ACTIVITY_CLEAR_TOP);
9998        closeSystemDialogs("assist");
9999        try {
10000            mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
10001        } catch (ActivityNotFoundException e) {
10002            Slog.w(TAG, "No activity to handle assist action.", e);
10003        }
10004    }
10005
10006    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle) {
10007        return enqueueAssistContext(requestType, intent, hint, userHandle) != null;
10008    }
10009
10010    public void registerProcessObserver(IProcessObserver observer) {
10011        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10012                "registerProcessObserver()");
10013        synchronized (this) {
10014            mProcessObservers.register(observer);
10015        }
10016    }
10017
10018    @Override
10019    public void unregisterProcessObserver(IProcessObserver observer) {
10020        synchronized (this) {
10021            mProcessObservers.unregister(observer);
10022        }
10023    }
10024
10025    @Override
10026    public boolean convertFromTranslucent(IBinder token) {
10027        final long origId = Binder.clearCallingIdentity();
10028        try {
10029            synchronized (this) {
10030                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10031                if (r == null) {
10032                    return false;
10033                }
10034                final boolean translucentChanged = r.changeWindowTranslucency(true);
10035                if (translucentChanged) {
10036                    r.task.stack.releaseBackgroundResources();
10037                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10038                }
10039                mWindowManager.setAppFullscreen(token, true);
10040                return translucentChanged;
10041            }
10042        } finally {
10043            Binder.restoreCallingIdentity(origId);
10044        }
10045    }
10046
10047    @Override
10048    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
10049        final long origId = Binder.clearCallingIdentity();
10050        try {
10051            synchronized (this) {
10052                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10053                if (r == null) {
10054                    return false;
10055                }
10056                int index = r.task.mActivities.lastIndexOf(r);
10057                if (index > 0) {
10058                    ActivityRecord under = r.task.mActivities.get(index - 1);
10059                    under.returningOptions = options;
10060                }
10061                final boolean translucentChanged = r.changeWindowTranslucency(false);
10062                if (translucentChanged) {
10063                    r.task.stack.convertToTranslucent(r);
10064                }
10065                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10066                mWindowManager.setAppFullscreen(token, false);
10067                return translucentChanged;
10068            }
10069        } finally {
10070            Binder.restoreCallingIdentity(origId);
10071        }
10072    }
10073
10074    @Override
10075    public boolean requestVisibleBehind(IBinder token, boolean visible) {
10076        final long origId = Binder.clearCallingIdentity();
10077        try {
10078            synchronized (this) {
10079                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10080                if (r != null) {
10081                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
10082                }
10083            }
10084            return false;
10085        } finally {
10086            Binder.restoreCallingIdentity(origId);
10087        }
10088    }
10089
10090    @Override
10091    public boolean isBackgroundVisibleBehind(IBinder token) {
10092        final long origId = Binder.clearCallingIdentity();
10093        try {
10094            synchronized (this) {
10095                final ActivityStack stack = ActivityRecord.getStackLocked(token);
10096                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
10097                if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG,
10098                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
10099                return visible;
10100            }
10101        } finally {
10102            Binder.restoreCallingIdentity(origId);
10103        }
10104    }
10105
10106    @Override
10107    public ActivityOptions getActivityOptions(IBinder token) {
10108        final long origId = Binder.clearCallingIdentity();
10109        try {
10110            synchronized (this) {
10111                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10112                if (r != null) {
10113                    final ActivityOptions activityOptions = r.pendingOptions;
10114                    r.pendingOptions = null;
10115                    return activityOptions;
10116                }
10117                return null;
10118            }
10119        } finally {
10120            Binder.restoreCallingIdentity(origId);
10121        }
10122    }
10123
10124    @Override
10125    public void setImmersive(IBinder token, boolean immersive) {
10126        synchronized(this) {
10127            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10128            if (r == null) {
10129                throw new IllegalArgumentException();
10130            }
10131            r.immersive = immersive;
10132
10133            // update associated state if we're frontmost
10134            if (r == mFocusedActivity) {
10135                if (DEBUG_IMMERSIVE) {
10136                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
10137                }
10138                applyUpdateLockStateLocked(r);
10139            }
10140        }
10141    }
10142
10143    @Override
10144    public boolean isImmersive(IBinder token) {
10145        synchronized (this) {
10146            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10147            if (r == null) {
10148                throw new IllegalArgumentException();
10149            }
10150            return r.immersive;
10151        }
10152    }
10153
10154    public boolean isTopActivityImmersive() {
10155        enforceNotIsolatedCaller("startActivity");
10156        synchronized (this) {
10157            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
10158            return (r != null) ? r.immersive : false;
10159        }
10160    }
10161
10162    @Override
10163    public boolean isTopOfTask(IBinder token) {
10164        synchronized (this) {
10165            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10166            if (r == null) {
10167                throw new IllegalArgumentException();
10168            }
10169            return r.task.getTopActivity() == r;
10170        }
10171    }
10172
10173    public final void enterSafeMode() {
10174        synchronized(this) {
10175            // It only makes sense to do this before the system is ready
10176            // and started launching other packages.
10177            if (!mSystemReady) {
10178                try {
10179                    AppGlobals.getPackageManager().enterSafeMode();
10180                } catch (RemoteException e) {
10181                }
10182            }
10183
10184            mSafeMode = true;
10185        }
10186    }
10187
10188    public final void showSafeModeOverlay() {
10189        View v = LayoutInflater.from(mContext).inflate(
10190                com.android.internal.R.layout.safe_mode, null);
10191        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
10192        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
10193        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
10194        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
10195        lp.gravity = Gravity.BOTTOM | Gravity.START;
10196        lp.format = v.getBackground().getOpacity();
10197        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
10198                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
10199        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
10200        ((WindowManager)mContext.getSystemService(
10201                Context.WINDOW_SERVICE)).addView(v, lp);
10202    }
10203
10204    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
10205        if (!(sender instanceof PendingIntentRecord)) {
10206            return;
10207        }
10208        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10209        synchronized (stats) {
10210            if (mBatteryStatsService.isOnBattery()) {
10211                mBatteryStatsService.enforceCallingPermission();
10212                PendingIntentRecord rec = (PendingIntentRecord)sender;
10213                int MY_UID = Binder.getCallingUid();
10214                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
10215                BatteryStatsImpl.Uid.Pkg pkg =
10216                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
10217                            sourcePkg != null ? sourcePkg : rec.key.packageName);
10218                pkg.incWakeupsLocked();
10219            }
10220        }
10221    }
10222
10223    public boolean killPids(int[] pids, String pReason, boolean secure) {
10224        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10225            throw new SecurityException("killPids only available to the system");
10226        }
10227        String reason = (pReason == null) ? "Unknown" : pReason;
10228        // XXX Note: don't acquire main activity lock here, because the window
10229        // manager calls in with its locks held.
10230
10231        boolean killed = false;
10232        synchronized (mPidsSelfLocked) {
10233            int[] types = new int[pids.length];
10234            int worstType = 0;
10235            for (int i=0; i<pids.length; i++) {
10236                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10237                if (proc != null) {
10238                    int type = proc.setAdj;
10239                    types[i] = type;
10240                    if (type > worstType) {
10241                        worstType = type;
10242                    }
10243                }
10244            }
10245
10246            // If the worst oom_adj is somewhere in the cached proc LRU range,
10247            // then constrain it so we will kill all cached procs.
10248            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
10249                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
10250                worstType = ProcessList.CACHED_APP_MIN_ADJ;
10251            }
10252
10253            // If this is not a secure call, don't let it kill processes that
10254            // are important.
10255            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
10256                worstType = ProcessList.SERVICE_ADJ;
10257            }
10258
10259            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
10260            for (int i=0; i<pids.length; i++) {
10261                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10262                if (proc == null) {
10263                    continue;
10264                }
10265                int adj = proc.setAdj;
10266                if (adj >= worstType && !proc.killedByAm) {
10267                    proc.kill(reason, true);
10268                    killed = true;
10269                }
10270            }
10271        }
10272        return killed;
10273    }
10274
10275    @Override
10276    public void killUid(int uid, String reason) {
10277        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10278            throw new SecurityException("killUid only available to the system");
10279        }
10280        synchronized (this) {
10281            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
10282                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
10283                    reason != null ? reason : "kill uid");
10284        }
10285    }
10286
10287    @Override
10288    public boolean killProcessesBelowForeground(String reason) {
10289        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10290            throw new SecurityException("killProcessesBelowForeground() only available to system");
10291        }
10292
10293        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
10294    }
10295
10296    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
10297        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10298            throw new SecurityException("killProcessesBelowAdj() only available to system");
10299        }
10300
10301        boolean killed = false;
10302        synchronized (mPidsSelfLocked) {
10303            final int size = mPidsSelfLocked.size();
10304            for (int i = 0; i < size; i++) {
10305                final int pid = mPidsSelfLocked.keyAt(i);
10306                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10307                if (proc == null) continue;
10308
10309                final int adj = proc.setAdj;
10310                if (adj > belowAdj && !proc.killedByAm) {
10311                    proc.kill(reason, true);
10312                    killed = true;
10313                }
10314            }
10315        }
10316        return killed;
10317    }
10318
10319    @Override
10320    public void hang(final IBinder who, boolean allowRestart) {
10321        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10322                != PackageManager.PERMISSION_GRANTED) {
10323            throw new SecurityException("Requires permission "
10324                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10325        }
10326
10327        final IBinder.DeathRecipient death = new DeathRecipient() {
10328            @Override
10329            public void binderDied() {
10330                synchronized (this) {
10331                    notifyAll();
10332                }
10333            }
10334        };
10335
10336        try {
10337            who.linkToDeath(death, 0);
10338        } catch (RemoteException e) {
10339            Slog.w(TAG, "hang: given caller IBinder is already dead.");
10340            return;
10341        }
10342
10343        synchronized (this) {
10344            Watchdog.getInstance().setAllowRestart(allowRestart);
10345            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
10346            synchronized (death) {
10347                while (who.isBinderAlive()) {
10348                    try {
10349                        death.wait();
10350                    } catch (InterruptedException e) {
10351                    }
10352                }
10353            }
10354            Watchdog.getInstance().setAllowRestart(true);
10355        }
10356    }
10357
10358    @Override
10359    public void restart() {
10360        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10361                != PackageManager.PERMISSION_GRANTED) {
10362            throw new SecurityException("Requires permission "
10363                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10364        }
10365
10366        Log.i(TAG, "Sending shutdown broadcast...");
10367
10368        BroadcastReceiver br = new BroadcastReceiver() {
10369            @Override public void onReceive(Context context, Intent intent) {
10370                // Now the broadcast is done, finish up the low-level shutdown.
10371                Log.i(TAG, "Shutting down activity manager...");
10372                shutdown(10000);
10373                Log.i(TAG, "Shutdown complete, restarting!");
10374                Process.killProcess(Process.myPid());
10375                System.exit(10);
10376            }
10377        };
10378
10379        // First send the high-level shut down broadcast.
10380        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
10381        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
10382        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
10383        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
10384        mContext.sendOrderedBroadcastAsUser(intent,
10385                UserHandle.ALL, null, br, mHandler, 0, null, null);
10386        */
10387        br.onReceive(mContext, intent);
10388    }
10389
10390    private long getLowRamTimeSinceIdle(long now) {
10391        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
10392    }
10393
10394    @Override
10395    public void performIdleMaintenance() {
10396        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10397                != PackageManager.PERMISSION_GRANTED) {
10398            throw new SecurityException("Requires permission "
10399                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10400        }
10401
10402        synchronized (this) {
10403            final long now = SystemClock.uptimeMillis();
10404            final long timeSinceLastIdle = now - mLastIdleTime;
10405            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
10406            mLastIdleTime = now;
10407            mLowRamTimeSinceLastIdle = 0;
10408            if (mLowRamStartTime != 0) {
10409                mLowRamStartTime = now;
10410            }
10411
10412            StringBuilder sb = new StringBuilder(128);
10413            sb.append("Idle maintenance over ");
10414            TimeUtils.formatDuration(timeSinceLastIdle, sb);
10415            sb.append(" low RAM for ");
10416            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
10417            Slog.i(TAG, sb.toString());
10418
10419            // If at least 1/3 of our time since the last idle period has been spent
10420            // with RAM low, then we want to kill processes.
10421            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
10422
10423            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
10424                ProcessRecord proc = mLruProcesses.get(i);
10425                if (proc.notCachedSinceIdle) {
10426                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
10427                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
10428                        if (doKilling && proc.initialIdlePss != 0
10429                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
10430                            sb = new StringBuilder(128);
10431                            sb.append("Kill");
10432                            sb.append(proc.processName);
10433                            sb.append(" in idle maint: pss=");
10434                            sb.append(proc.lastPss);
10435                            sb.append(", initialPss=");
10436                            sb.append(proc.initialIdlePss);
10437                            sb.append(", period=");
10438                            TimeUtils.formatDuration(timeSinceLastIdle, sb);
10439                            sb.append(", lowRamPeriod=");
10440                            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
10441                            Slog.wtfQuiet(TAG, sb.toString());
10442                            proc.kill("idle maint (pss " + proc.lastPss
10443                                    + " from " + proc.initialIdlePss + ")", true);
10444                        }
10445                    }
10446                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
10447                    proc.notCachedSinceIdle = true;
10448                    proc.initialIdlePss = 0;
10449                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
10450                            mTestPssMode, isSleeping(), now);
10451                }
10452            }
10453
10454            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
10455            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
10456        }
10457    }
10458
10459    private void retrieveSettings() {
10460        final ContentResolver resolver = mContext.getContentResolver();
10461        String debugApp = Settings.Global.getString(
10462            resolver, Settings.Global.DEBUG_APP);
10463        boolean waitForDebugger = Settings.Global.getInt(
10464            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
10465        boolean alwaysFinishActivities = Settings.Global.getInt(
10466            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
10467        boolean forceRtl = Settings.Global.getInt(
10468                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
10469        // Transfer any global setting for forcing RTL layout, into a System Property
10470        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
10471
10472        Configuration configuration = new Configuration();
10473        Settings.System.getConfiguration(resolver, configuration);
10474        if (forceRtl) {
10475            // This will take care of setting the correct layout direction flags
10476            configuration.setLayoutDirection(configuration.locale);
10477        }
10478
10479        synchronized (this) {
10480            mDebugApp = mOrigDebugApp = debugApp;
10481            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
10482            mAlwaysFinishActivities = alwaysFinishActivities;
10483            // This happens before any activities are started, so we can
10484            // change mConfiguration in-place.
10485            updateConfigurationLocked(configuration, null, false, true);
10486            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
10487        }
10488    }
10489
10490    /** Loads resources after the current configuration has been set. */
10491    private void loadResourcesOnSystemReady() {
10492        final Resources res = mContext.getResources();
10493        mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
10494        mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
10495        mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
10496    }
10497
10498    public boolean testIsSystemReady() {
10499        // no need to synchronize(this) just to read & return the value
10500        return mSystemReady;
10501    }
10502
10503    private static File getCalledPreBootReceiversFile() {
10504        File dataDir = Environment.getDataDirectory();
10505        File systemDir = new File(dataDir, "system");
10506        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
10507        return fname;
10508    }
10509
10510    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
10511        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
10512        File file = getCalledPreBootReceiversFile();
10513        FileInputStream fis = null;
10514        try {
10515            fis = new FileInputStream(file);
10516            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
10517            int fvers = dis.readInt();
10518            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
10519                String vers = dis.readUTF();
10520                String codename = dis.readUTF();
10521                String build = dis.readUTF();
10522                if (android.os.Build.VERSION.RELEASE.equals(vers)
10523                        && android.os.Build.VERSION.CODENAME.equals(codename)
10524                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
10525                    int num = dis.readInt();
10526                    while (num > 0) {
10527                        num--;
10528                        String pkg = dis.readUTF();
10529                        String cls = dis.readUTF();
10530                        lastDoneReceivers.add(new ComponentName(pkg, cls));
10531                    }
10532                }
10533            }
10534        } catch (FileNotFoundException e) {
10535        } catch (IOException e) {
10536            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
10537        } finally {
10538            if (fis != null) {
10539                try {
10540                    fis.close();
10541                } catch (IOException e) {
10542                }
10543            }
10544        }
10545        return lastDoneReceivers;
10546    }
10547
10548    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
10549        File file = getCalledPreBootReceiversFile();
10550        FileOutputStream fos = null;
10551        DataOutputStream dos = null;
10552        try {
10553            fos = new FileOutputStream(file);
10554            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
10555            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
10556            dos.writeUTF(android.os.Build.VERSION.RELEASE);
10557            dos.writeUTF(android.os.Build.VERSION.CODENAME);
10558            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
10559            dos.writeInt(list.size());
10560            for (int i=0; i<list.size(); i++) {
10561                dos.writeUTF(list.get(i).getPackageName());
10562                dos.writeUTF(list.get(i).getClassName());
10563            }
10564        } catch (IOException e) {
10565            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
10566            file.delete();
10567        } finally {
10568            FileUtils.sync(fos);
10569            if (dos != null) {
10570                try {
10571                    dos.close();
10572                } catch (IOException e) {
10573                    // TODO Auto-generated catch block
10574                    e.printStackTrace();
10575                }
10576            }
10577        }
10578    }
10579
10580    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
10581            ArrayList<ComponentName> doneReceivers, int userId) {
10582        boolean waitingUpdate = false;
10583        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
10584        List<ResolveInfo> ris = null;
10585        try {
10586            ris = AppGlobals.getPackageManager().queryIntentReceivers(
10587                    intent, null, 0, userId);
10588        } catch (RemoteException e) {
10589        }
10590        if (ris != null) {
10591            for (int i=ris.size()-1; i>=0; i--) {
10592                if ((ris.get(i).activityInfo.applicationInfo.flags
10593                        &ApplicationInfo.FLAG_SYSTEM) == 0) {
10594                    ris.remove(i);
10595                }
10596            }
10597            intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
10598
10599            // For User 0, load the version number. When delivering to a new user, deliver
10600            // to all receivers.
10601            if (userId == UserHandle.USER_OWNER) {
10602                ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
10603                for (int i=0; i<ris.size(); i++) {
10604                    ActivityInfo ai = ris.get(i).activityInfo;
10605                    ComponentName comp = new ComponentName(ai.packageName, ai.name);
10606                    if (lastDoneReceivers.contains(comp)) {
10607                        // We already did the pre boot receiver for this app with the current
10608                        // platform version, so don't do it again...
10609                        ris.remove(i);
10610                        i--;
10611                        // ...however, do keep it as one that has been done, so we don't
10612                        // forget about it when rewriting the file of last done receivers.
10613                        doneReceivers.add(comp);
10614                    }
10615                }
10616            }
10617
10618            // If primary user, send broadcast to all available users, else just to userId
10619            final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
10620                    : new int[] { userId };
10621            for (int i = 0; i < ris.size(); i++) {
10622                ActivityInfo ai = ris.get(i).activityInfo;
10623                ComponentName comp = new ComponentName(ai.packageName, ai.name);
10624                doneReceivers.add(comp);
10625                intent.setComponent(comp);
10626                for (int j=0; j<users.length; j++) {
10627                    IIntentReceiver finisher = null;
10628                    // On last receiver and user, set up a completion callback
10629                    if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) {
10630                        finisher = new IIntentReceiver.Stub() {
10631                            public void performReceive(Intent intent, int resultCode,
10632                                    String data, Bundle extras, boolean ordered,
10633                                    boolean sticky, int sendingUser) {
10634                                // The raw IIntentReceiver interface is called
10635                                // with the AM lock held, so redispatch to
10636                                // execute our code without the lock.
10637                                mHandler.post(onFinishCallback);
10638                            }
10639                        };
10640                    }
10641                    Slog.i(TAG, "Sending system update to " + intent.getComponent()
10642                            + " for user " + users[j]);
10643                    broadcastIntentLocked(null, null, intent, null, finisher,
10644                            0, null, null, null, AppOpsManager.OP_NONE,
10645                            true, false, MY_PID, Process.SYSTEM_UID,
10646                            users[j]);
10647                    if (finisher != null) {
10648                        waitingUpdate = true;
10649                    }
10650                }
10651            }
10652        }
10653
10654        return waitingUpdate;
10655    }
10656
10657    public void systemReady(final Runnable goingCallback) {
10658        synchronized(this) {
10659            if (mSystemReady) {
10660                // If we're done calling all the receivers, run the next "boot phase" passed in
10661                // by the SystemServer
10662                if (goingCallback != null) {
10663                    goingCallback.run();
10664                }
10665                return;
10666            }
10667
10668            // Make sure we have the current profile info, since it is needed for
10669            // security checks.
10670            updateCurrentProfileIdsLocked();
10671
10672            mRecentTasks.clear();
10673            mRecentTasks.addAll(mTaskPersister.restoreTasksLocked());
10674            mTaskPersister.restoreTasksFromOtherDeviceLocked();
10675            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
10676            mTaskPersister.startPersisting();
10677
10678            // Check to see if there are any update receivers to run.
10679            if (!mDidUpdate) {
10680                if (mWaitingUpdate) {
10681                    return;
10682                }
10683                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
10684                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
10685                    public void run() {
10686                        synchronized (ActivityManagerService.this) {
10687                            mDidUpdate = true;
10688                        }
10689                        writeLastDonePreBootReceivers(doneReceivers);
10690                        showBootMessage(mContext.getText(
10691                                R.string.android_upgrading_complete),
10692                                false);
10693                        systemReady(goingCallback);
10694                    }
10695                }, doneReceivers, UserHandle.USER_OWNER);
10696
10697                if (mWaitingUpdate) {
10698                    return;
10699                }
10700                mDidUpdate = true;
10701            }
10702
10703            mAppOpsService.systemReady();
10704            mSystemReady = true;
10705        }
10706
10707        ArrayList<ProcessRecord> procsToKill = null;
10708        synchronized(mPidsSelfLocked) {
10709            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
10710                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10711                if (!isAllowedWhileBooting(proc.info)){
10712                    if (procsToKill == null) {
10713                        procsToKill = new ArrayList<ProcessRecord>();
10714                    }
10715                    procsToKill.add(proc);
10716                }
10717            }
10718        }
10719
10720        synchronized(this) {
10721            if (procsToKill != null) {
10722                for (int i=procsToKill.size()-1; i>=0; i--) {
10723                    ProcessRecord proc = procsToKill.get(i);
10724                    Slog.i(TAG, "Removing system update proc: " + proc);
10725                    removeProcessLocked(proc, true, false, "system update done");
10726                }
10727            }
10728
10729            // Now that we have cleaned up any update processes, we
10730            // are ready to start launching real processes and know that
10731            // we won't trample on them any more.
10732            mProcessesReady = true;
10733        }
10734
10735        Slog.i(TAG, "System now ready");
10736        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
10737            SystemClock.uptimeMillis());
10738
10739        synchronized(this) {
10740            // Make sure we have no pre-ready processes sitting around.
10741
10742            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
10743                ResolveInfo ri = mContext.getPackageManager()
10744                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
10745                                STOCK_PM_FLAGS);
10746                CharSequence errorMsg = null;
10747                if (ri != null) {
10748                    ActivityInfo ai = ri.activityInfo;
10749                    ApplicationInfo app = ai.applicationInfo;
10750                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
10751                        mTopAction = Intent.ACTION_FACTORY_TEST;
10752                        mTopData = null;
10753                        mTopComponent = new ComponentName(app.packageName,
10754                                ai.name);
10755                    } else {
10756                        errorMsg = mContext.getResources().getText(
10757                                com.android.internal.R.string.factorytest_not_system);
10758                    }
10759                } else {
10760                    errorMsg = mContext.getResources().getText(
10761                            com.android.internal.R.string.factorytest_no_action);
10762                }
10763                if (errorMsg != null) {
10764                    mTopAction = null;
10765                    mTopData = null;
10766                    mTopComponent = null;
10767                    Message msg = Message.obtain();
10768                    msg.what = SHOW_FACTORY_ERROR_MSG;
10769                    msg.getData().putCharSequence("msg", errorMsg);
10770                    mHandler.sendMessage(msg);
10771                }
10772            }
10773        }
10774
10775        retrieveSettings();
10776        loadResourcesOnSystemReady();
10777
10778        synchronized (this) {
10779            readGrantedUriPermissionsLocked();
10780        }
10781
10782        if (goingCallback != null) goingCallback.run();
10783
10784        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
10785                Integer.toString(mCurrentUserId), mCurrentUserId);
10786        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
10787                Integer.toString(mCurrentUserId), mCurrentUserId);
10788        mSystemServiceManager.startUser(mCurrentUserId);
10789
10790        synchronized (this) {
10791            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
10792                try {
10793                    List apps = AppGlobals.getPackageManager().
10794                        getPersistentApplications(STOCK_PM_FLAGS);
10795                    if (apps != null) {
10796                        int N = apps.size();
10797                        int i;
10798                        for (i=0; i<N; i++) {
10799                            ApplicationInfo info
10800                                = (ApplicationInfo)apps.get(i);
10801                            if (info != null &&
10802                                    !info.packageName.equals("android")) {
10803                                addAppLocked(info, false, null /* ABI override */);
10804                            }
10805                        }
10806                    }
10807                } catch (RemoteException ex) {
10808                    // pm is in same process, this will never happen.
10809                }
10810            }
10811
10812            // Start up initial activity.
10813            mBooting = true;
10814            startHomeActivityLocked(mCurrentUserId);
10815
10816            try {
10817                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
10818                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
10819                            + " data partition or your device will be unstable.");
10820                    mHandler.obtainMessage(SHOW_UID_ERROR_MSG).sendToTarget();
10821                }
10822            } catch (RemoteException e) {
10823            }
10824
10825            if (!Build.isFingerprintConsistent()) {
10826                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
10827                mHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_MSG).sendToTarget();
10828            }
10829
10830            long ident = Binder.clearCallingIdentity();
10831            try {
10832                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
10833                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
10834                        | Intent.FLAG_RECEIVER_FOREGROUND);
10835                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
10836                broadcastIntentLocked(null, null, intent,
10837                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
10838                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
10839                intent = new Intent(Intent.ACTION_USER_STARTING);
10840                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
10841                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
10842                broadcastIntentLocked(null, null, intent,
10843                        null, new IIntentReceiver.Stub() {
10844                            @Override
10845                            public void performReceive(Intent intent, int resultCode, String data,
10846                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
10847                                    throws RemoteException {
10848                            }
10849                        }, 0, null, null,
10850                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
10851                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
10852            } catch (Throwable t) {
10853                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
10854            } finally {
10855                Binder.restoreCallingIdentity(ident);
10856            }
10857            mStackSupervisor.resumeTopActivitiesLocked();
10858            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
10859        }
10860    }
10861
10862    private boolean makeAppCrashingLocked(ProcessRecord app,
10863            String shortMsg, String longMsg, String stackTrace) {
10864        app.crashing = true;
10865        app.crashingReport = generateProcessError(app,
10866                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
10867        startAppProblemLocked(app);
10868        app.stopFreezingAllLocked();
10869        return handleAppCrashLocked(app, "force-crash" /*reason*/, shortMsg, longMsg, stackTrace);
10870    }
10871
10872    private void makeAppNotRespondingLocked(ProcessRecord app,
10873            String activity, String shortMsg, String longMsg) {
10874        app.notResponding = true;
10875        app.notRespondingReport = generateProcessError(app,
10876                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
10877                activity, shortMsg, longMsg, null);
10878        startAppProblemLocked(app);
10879        app.stopFreezingAllLocked();
10880    }
10881
10882    /**
10883     * Generate a process error record, suitable for attachment to a ProcessRecord.
10884     *
10885     * @param app The ProcessRecord in which the error occurred.
10886     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
10887     *                      ActivityManager.AppErrorStateInfo
10888     * @param activity The activity associated with the crash, if known.
10889     * @param shortMsg Short message describing the crash.
10890     * @param longMsg Long message describing the crash.
10891     * @param stackTrace Full crash stack trace, may be null.
10892     *
10893     * @return Returns a fully-formed AppErrorStateInfo record.
10894     */
10895    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
10896            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
10897        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
10898
10899        report.condition = condition;
10900        report.processName = app.processName;
10901        report.pid = app.pid;
10902        report.uid = app.info.uid;
10903        report.tag = activity;
10904        report.shortMsg = shortMsg;
10905        report.longMsg = longMsg;
10906        report.stackTrace = stackTrace;
10907
10908        return report;
10909    }
10910
10911    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
10912        synchronized (this) {
10913            app.crashing = false;
10914            app.crashingReport = null;
10915            app.notResponding = false;
10916            app.notRespondingReport = null;
10917            if (app.anrDialog == fromDialog) {
10918                app.anrDialog = null;
10919            }
10920            if (app.waitDialog == fromDialog) {
10921                app.waitDialog = null;
10922            }
10923            if (app.pid > 0 && app.pid != MY_PID) {
10924                handleAppCrashLocked(app, "user-terminated" /*reason*/,
10925                        null /*shortMsg*/, null /*longMsg*/, null /*stackTrace*/);
10926                app.kill("user request after error", true);
10927            }
10928        }
10929    }
10930
10931    private boolean handleAppCrashLocked(ProcessRecord app, String reason,
10932            String shortMsg, String longMsg, String stackTrace) {
10933        long now = SystemClock.uptimeMillis();
10934
10935        Long crashTime;
10936        if (!app.isolated) {
10937            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
10938        } else {
10939            crashTime = null;
10940        }
10941        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
10942            // This process loses!
10943            Slog.w(TAG, "Process " + app.info.processName
10944                    + " has crashed too many times: killing!");
10945            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
10946                    app.userId, app.info.processName, app.uid);
10947            mStackSupervisor.handleAppCrashLocked(app);
10948            if (!app.persistent) {
10949                // We don't want to start this process again until the user
10950                // explicitly does so...  but for persistent process, we really
10951                // need to keep it running.  If a persistent process is actually
10952                // repeatedly crashing, then badness for everyone.
10953                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
10954                        app.info.processName);
10955                if (!app.isolated) {
10956                    // XXX We don't have a way to mark isolated processes
10957                    // as bad, since they don't have a peristent identity.
10958                    mBadProcesses.put(app.info.processName, app.uid,
10959                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
10960                    mProcessCrashTimes.remove(app.info.processName, app.uid);
10961                }
10962                app.bad = true;
10963                app.removed = true;
10964                // Don't let services in this process be restarted and potentially
10965                // annoy the user repeatedly.  Unless it is persistent, since those
10966                // processes run critical code.
10967                removeProcessLocked(app, false, false, "crash");
10968                mStackSupervisor.resumeTopActivitiesLocked();
10969                return false;
10970            }
10971            mStackSupervisor.resumeTopActivitiesLocked();
10972        } else {
10973            mStackSupervisor.finishTopRunningActivityLocked(app, reason);
10974        }
10975
10976        // Bump up the crash count of any services currently running in the proc.
10977        for (int i=app.services.size()-1; i>=0; i--) {
10978            // Any services running in the application need to be placed
10979            // back in the pending list.
10980            ServiceRecord sr = app.services.valueAt(i);
10981            sr.crashCount++;
10982        }
10983
10984        // If the crashing process is what we consider to be the "home process" and it has been
10985        // replaced by a third-party app, clear the package preferred activities from packages
10986        // with a home activity running in the process to prevent a repeatedly crashing app
10987        // from blocking the user to manually clear the list.
10988        final ArrayList<ActivityRecord> activities = app.activities;
10989        if (app == mHomeProcess && activities.size() > 0
10990                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
10991            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
10992                final ActivityRecord r = activities.get(activityNdx);
10993                if (r.isHomeActivity()) {
10994                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
10995                    try {
10996                        ActivityThread.getPackageManager()
10997                                .clearPackagePreferredActivities(r.packageName);
10998                    } catch (RemoteException c) {
10999                        // pm is in same process, this will never happen.
11000                    }
11001                }
11002            }
11003        }
11004
11005        if (!app.isolated) {
11006            // XXX Can't keep track of crash times for isolated processes,
11007            // because they don't have a perisistent identity.
11008            mProcessCrashTimes.put(app.info.processName, app.uid, now);
11009        }
11010
11011        if (app.crashHandler != null) mHandler.post(app.crashHandler);
11012        return true;
11013    }
11014
11015    void startAppProblemLocked(ProcessRecord app) {
11016        // If this app is not running under the current user, then we
11017        // can't give it a report button because that would require
11018        // launching the report UI under a different user.
11019        app.errorReportReceiver = null;
11020
11021        for (int userId : mCurrentProfileIds) {
11022            if (app.userId == userId) {
11023                app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
11024                        mContext, app.info.packageName, app.info.flags);
11025            }
11026        }
11027        skipCurrentReceiverLocked(app);
11028    }
11029
11030    void skipCurrentReceiverLocked(ProcessRecord app) {
11031        for (BroadcastQueue queue : mBroadcastQueues) {
11032            queue.skipCurrentReceiverLocked(app);
11033        }
11034    }
11035
11036    /**
11037     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
11038     * The application process will exit immediately after this call returns.
11039     * @param app object of the crashing app, null for the system server
11040     * @param crashInfo describing the exception
11041     */
11042    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
11043        ProcessRecord r = findAppProcess(app, "Crash");
11044        final String processName = app == null ? "system_server"
11045                : (r == null ? "unknown" : r.processName);
11046
11047        handleApplicationCrashInner("crash", r, processName, crashInfo);
11048    }
11049
11050    /* Native crash reporting uses this inner version because it needs to be somewhat
11051     * decoupled from the AM-managed cleanup lifecycle
11052     */
11053    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
11054            ApplicationErrorReport.CrashInfo crashInfo) {
11055        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
11056                UserHandle.getUserId(Binder.getCallingUid()), processName,
11057                r == null ? -1 : r.info.flags,
11058                crashInfo.exceptionClassName,
11059                crashInfo.exceptionMessage,
11060                crashInfo.throwFileName,
11061                crashInfo.throwLineNumber);
11062
11063        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
11064
11065        crashApplication(r, crashInfo);
11066    }
11067
11068    public void handleApplicationStrictModeViolation(
11069            IBinder app,
11070            int violationMask,
11071            StrictMode.ViolationInfo info) {
11072        ProcessRecord r = findAppProcess(app, "StrictMode");
11073        if (r == null) {
11074            return;
11075        }
11076
11077        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
11078            Integer stackFingerprint = info.hashCode();
11079            boolean logIt = true;
11080            synchronized (mAlreadyLoggedViolatedStacks) {
11081                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
11082                    logIt = false;
11083                    // TODO: sub-sample into EventLog for these, with
11084                    // the info.durationMillis?  Then we'd get
11085                    // the relative pain numbers, without logging all
11086                    // the stack traces repeatedly.  We'd want to do
11087                    // likewise in the client code, which also does
11088                    // dup suppression, before the Binder call.
11089                } else {
11090                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
11091                        mAlreadyLoggedViolatedStacks.clear();
11092                    }
11093                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
11094                }
11095            }
11096            if (logIt) {
11097                logStrictModeViolationToDropBox(r, info);
11098            }
11099        }
11100
11101        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
11102            AppErrorResult result = new AppErrorResult();
11103            synchronized (this) {
11104                final long origId = Binder.clearCallingIdentity();
11105
11106                Message msg = Message.obtain();
11107                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
11108                HashMap<String, Object> data = new HashMap<String, Object>();
11109                data.put("result", result);
11110                data.put("app", r);
11111                data.put("violationMask", violationMask);
11112                data.put("info", info);
11113                msg.obj = data;
11114                mHandler.sendMessage(msg);
11115
11116                Binder.restoreCallingIdentity(origId);
11117            }
11118            int res = result.get();
11119            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
11120        }
11121    }
11122
11123    // Depending on the policy in effect, there could be a bunch of
11124    // these in quick succession so we try to batch these together to
11125    // minimize disk writes, number of dropbox entries, and maximize
11126    // compression, by having more fewer, larger records.
11127    private void logStrictModeViolationToDropBox(
11128            ProcessRecord process,
11129            StrictMode.ViolationInfo info) {
11130        if (info == null) {
11131            return;
11132        }
11133        final boolean isSystemApp = process == null ||
11134                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
11135                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
11136        final String processName = process == null ? "unknown" : process.processName;
11137        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
11138        final DropBoxManager dbox = (DropBoxManager)
11139                mContext.getSystemService(Context.DROPBOX_SERVICE);
11140
11141        // Exit early if the dropbox isn't configured to accept this report type.
11142        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11143
11144        boolean bufferWasEmpty;
11145        boolean needsFlush;
11146        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
11147        synchronized (sb) {
11148            bufferWasEmpty = sb.length() == 0;
11149            appendDropBoxProcessHeaders(process, processName, sb);
11150            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11151            sb.append("System-App: ").append(isSystemApp).append("\n");
11152            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
11153            if (info.violationNumThisLoop != 0) {
11154                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
11155            }
11156            if (info.numAnimationsRunning != 0) {
11157                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
11158            }
11159            if (info.broadcastIntentAction != null) {
11160                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
11161            }
11162            if (info.durationMillis != -1) {
11163                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
11164            }
11165            if (info.numInstances != -1) {
11166                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
11167            }
11168            if (info.tags != null) {
11169                for (String tag : info.tags) {
11170                    sb.append("Span-Tag: ").append(tag).append("\n");
11171                }
11172            }
11173            sb.append("\n");
11174            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
11175                sb.append(info.crashInfo.stackTrace);
11176                sb.append("\n");
11177            }
11178            if (info.message != null) {
11179                sb.append(info.message);
11180                sb.append("\n");
11181            }
11182
11183            // Only buffer up to ~64k.  Various logging bits truncate
11184            // things at 128k.
11185            needsFlush = (sb.length() > 64 * 1024);
11186        }
11187
11188        // Flush immediately if the buffer's grown too large, or this
11189        // is a non-system app.  Non-system apps are isolated with a
11190        // different tag & policy and not batched.
11191        //
11192        // Batching is useful during internal testing with
11193        // StrictMode settings turned up high.  Without batching,
11194        // thousands of separate files could be created on boot.
11195        if (!isSystemApp || needsFlush) {
11196            new Thread("Error dump: " + dropboxTag) {
11197                @Override
11198                public void run() {
11199                    String report;
11200                    synchronized (sb) {
11201                        report = sb.toString();
11202                        sb.delete(0, sb.length());
11203                        sb.trimToSize();
11204                    }
11205                    if (report.length() != 0) {
11206                        dbox.addText(dropboxTag, report);
11207                    }
11208                }
11209            }.start();
11210            return;
11211        }
11212
11213        // System app batching:
11214        if (!bufferWasEmpty) {
11215            // An existing dropbox-writing thread is outstanding, so
11216            // we don't need to start it up.  The existing thread will
11217            // catch the buffer appends we just did.
11218            return;
11219        }
11220
11221        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
11222        // (After this point, we shouldn't access AMS internal data structures.)
11223        new Thread("Error dump: " + dropboxTag) {
11224            @Override
11225            public void run() {
11226                // 5 second sleep to let stacks arrive and be batched together
11227                try {
11228                    Thread.sleep(5000);  // 5 seconds
11229                } catch (InterruptedException e) {}
11230
11231                String errorReport;
11232                synchronized (mStrictModeBuffer) {
11233                    errorReport = mStrictModeBuffer.toString();
11234                    if (errorReport.length() == 0) {
11235                        return;
11236                    }
11237                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
11238                    mStrictModeBuffer.trimToSize();
11239                }
11240                dbox.addText(dropboxTag, errorReport);
11241            }
11242        }.start();
11243    }
11244
11245    /**
11246     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
11247     * @param app object of the crashing app, null for the system server
11248     * @param tag reported by the caller
11249     * @param system whether this wtf is coming from the system
11250     * @param crashInfo describing the context of the error
11251     * @return true if the process should exit immediately (WTF is fatal)
11252     */
11253    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
11254            final ApplicationErrorReport.CrashInfo crashInfo) {
11255        final int callingUid = Binder.getCallingUid();
11256        final int callingPid = Binder.getCallingPid();
11257
11258        if (system) {
11259            // If this is coming from the system, we could very well have low-level
11260            // system locks held, so we want to do this all asynchronously.  And we
11261            // never want this to become fatal, so there is that too.
11262            mHandler.post(new Runnable() {
11263                @Override public void run() {
11264                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
11265                }
11266            });
11267            return false;
11268        }
11269
11270        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
11271                crashInfo);
11272
11273        if (r != null && r.pid != Process.myPid() &&
11274                Settings.Global.getInt(mContext.getContentResolver(),
11275                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
11276            crashApplication(r, crashInfo);
11277            return true;
11278        } else {
11279            return false;
11280        }
11281    }
11282
11283    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
11284            final ApplicationErrorReport.CrashInfo crashInfo) {
11285        final ProcessRecord r = findAppProcess(app, "WTF");
11286        final String processName = app == null ? "system_server"
11287                : (r == null ? "unknown" : r.processName);
11288
11289        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
11290                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
11291
11292        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
11293
11294        return r;
11295    }
11296
11297    /**
11298     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
11299     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
11300     */
11301    private ProcessRecord findAppProcess(IBinder app, String reason) {
11302        if (app == null) {
11303            return null;
11304        }
11305
11306        synchronized (this) {
11307            final int NP = mProcessNames.getMap().size();
11308            for (int ip=0; ip<NP; ip++) {
11309                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11310                final int NA = apps.size();
11311                for (int ia=0; ia<NA; ia++) {
11312                    ProcessRecord p = apps.valueAt(ia);
11313                    if (p.thread != null && p.thread.asBinder() == app) {
11314                        return p;
11315                    }
11316                }
11317            }
11318
11319            Slog.w(TAG, "Can't find mystery application for " + reason
11320                    + " from pid=" + Binder.getCallingPid()
11321                    + " uid=" + Binder.getCallingUid() + ": " + app);
11322            return null;
11323        }
11324    }
11325
11326    /**
11327     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
11328     * to append various headers to the dropbox log text.
11329     */
11330    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
11331            StringBuilder sb) {
11332        // Watchdog thread ends up invoking this function (with
11333        // a null ProcessRecord) to add the stack file to dropbox.
11334        // Do not acquire a lock on this (am) in such cases, as it
11335        // could cause a potential deadlock, if and when watchdog
11336        // is invoked due to unavailability of lock on am and it
11337        // would prevent watchdog from killing system_server.
11338        if (process == null) {
11339            sb.append("Process: ").append(processName).append("\n");
11340            return;
11341        }
11342        // Note: ProcessRecord 'process' is guarded by the service
11343        // instance.  (notably process.pkgList, which could otherwise change
11344        // concurrently during execution of this method)
11345        synchronized (this) {
11346            sb.append("Process: ").append(processName).append("\n");
11347            int flags = process.info.flags;
11348            IPackageManager pm = AppGlobals.getPackageManager();
11349            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
11350            for (int ip=0; ip<process.pkgList.size(); ip++) {
11351                String pkg = process.pkgList.keyAt(ip);
11352                sb.append("Package: ").append(pkg);
11353                try {
11354                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
11355                    if (pi != null) {
11356                        sb.append(" v").append(pi.versionCode);
11357                        if (pi.versionName != null) {
11358                            sb.append(" (").append(pi.versionName).append(")");
11359                        }
11360                    }
11361                } catch (RemoteException e) {
11362                    Slog.e(TAG, "Error getting package info: " + pkg, e);
11363                }
11364                sb.append("\n");
11365            }
11366        }
11367    }
11368
11369    private static String processClass(ProcessRecord process) {
11370        if (process == null || process.pid == MY_PID) {
11371            return "system_server";
11372        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
11373            return "system_app";
11374        } else {
11375            return "data_app";
11376        }
11377    }
11378
11379    /**
11380     * Write a description of an error (crash, WTF, ANR) to the drop box.
11381     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
11382     * @param process which caused the error, null means the system server
11383     * @param activity which triggered the error, null if unknown
11384     * @param parent activity related to the error, null if unknown
11385     * @param subject line related to the error, null if absent
11386     * @param report in long form describing the error, null if absent
11387     * @param logFile to include in the report, null if none
11388     * @param crashInfo giving an application stack trace, null if absent
11389     */
11390    public void addErrorToDropBox(String eventType,
11391            ProcessRecord process, String processName, ActivityRecord activity,
11392            ActivityRecord parent, String subject,
11393            final String report, final File logFile,
11394            final ApplicationErrorReport.CrashInfo crashInfo) {
11395        // NOTE -- this must never acquire the ActivityManagerService lock,
11396        // otherwise the watchdog may be prevented from resetting the system.
11397
11398        final String dropboxTag = processClass(process) + "_" + eventType;
11399        final DropBoxManager dbox = (DropBoxManager)
11400                mContext.getSystemService(Context.DROPBOX_SERVICE);
11401
11402        // Exit early if the dropbox isn't configured to accept this report type.
11403        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11404
11405        final StringBuilder sb = new StringBuilder(1024);
11406        appendDropBoxProcessHeaders(process, processName, sb);
11407        if (activity != null) {
11408            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
11409        }
11410        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
11411            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
11412        }
11413        if (parent != null && parent != activity) {
11414            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
11415        }
11416        if (subject != null) {
11417            sb.append("Subject: ").append(subject).append("\n");
11418        }
11419        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11420        if (Debug.isDebuggerConnected()) {
11421            sb.append("Debugger: Connected\n");
11422        }
11423        sb.append("\n");
11424
11425        // Do the rest in a worker thread to avoid blocking the caller on I/O
11426        // (After this point, we shouldn't access AMS internal data structures.)
11427        Thread worker = new Thread("Error dump: " + dropboxTag) {
11428            @Override
11429            public void run() {
11430                if (report != null) {
11431                    sb.append(report);
11432                }
11433                if (logFile != null) {
11434                    try {
11435                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
11436                                    "\n\n[[TRUNCATED]]"));
11437                    } catch (IOException e) {
11438                        Slog.e(TAG, "Error reading " + logFile, e);
11439                    }
11440                }
11441                if (crashInfo != null && crashInfo.stackTrace != null) {
11442                    sb.append(crashInfo.stackTrace);
11443                }
11444
11445                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
11446                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
11447                if (lines > 0) {
11448                    sb.append("\n");
11449
11450                    // Merge several logcat streams, and take the last N lines
11451                    InputStreamReader input = null;
11452                    try {
11453                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
11454                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
11455                                "-b", "crash",
11456                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
11457
11458                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
11459                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
11460                        input = new InputStreamReader(logcat.getInputStream());
11461
11462                        int num;
11463                        char[] buf = new char[8192];
11464                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
11465                    } catch (IOException e) {
11466                        Slog.e(TAG, "Error running logcat", e);
11467                    } finally {
11468                        if (input != null) try { input.close(); } catch (IOException e) {}
11469                    }
11470                }
11471
11472                dbox.addText(dropboxTag, sb.toString());
11473            }
11474        };
11475
11476        if (process == null) {
11477            // If process is null, we are being called from some internal code
11478            // and may be about to die -- run this synchronously.
11479            worker.run();
11480        } else {
11481            worker.start();
11482        }
11483    }
11484
11485    /**
11486     * Bring up the "unexpected error" dialog box for a crashing app.
11487     * Deal with edge cases (intercepts from instrumented applications,
11488     * ActivityController, error intent receivers, that sort of thing).
11489     * @param r the application crashing
11490     * @param crashInfo describing the failure
11491     */
11492    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
11493        long timeMillis = System.currentTimeMillis();
11494        String shortMsg = crashInfo.exceptionClassName;
11495        String longMsg = crashInfo.exceptionMessage;
11496        String stackTrace = crashInfo.stackTrace;
11497        if (shortMsg != null && longMsg != null) {
11498            longMsg = shortMsg + ": " + longMsg;
11499        } else if (shortMsg != null) {
11500            longMsg = shortMsg;
11501        }
11502
11503        AppErrorResult result = new AppErrorResult();
11504        synchronized (this) {
11505            if (mController != null) {
11506                try {
11507                    String name = r != null ? r.processName : null;
11508                    int pid = r != null ? r.pid : Binder.getCallingPid();
11509                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
11510                    if (!mController.appCrashed(name, pid,
11511                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
11512                        if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
11513                                && "Native crash".equals(crashInfo.exceptionClassName)) {
11514                            Slog.w(TAG, "Skip killing native crashed app " + name
11515                                    + "(" + pid + ") during testing");
11516                        } else {
11517                            Slog.w(TAG, "Force-killing crashed app " + name
11518                                    + " at watcher's request");
11519                            if (r != null) {
11520                                r.kill("crash", true);
11521                            } else {
11522                                // Huh.
11523                                Process.killProcess(pid);
11524                                Process.killProcessGroup(uid, pid);
11525                            }
11526                        }
11527                        return;
11528                    }
11529                } catch (RemoteException e) {
11530                    mController = null;
11531                    Watchdog.getInstance().setActivityController(null);
11532                }
11533            }
11534
11535            final long origId = Binder.clearCallingIdentity();
11536
11537            // If this process is running instrumentation, finish it.
11538            if (r != null && r.instrumentationClass != null) {
11539                Slog.w(TAG, "Error in app " + r.processName
11540                      + " running instrumentation " + r.instrumentationClass + ":");
11541                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
11542                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
11543                Bundle info = new Bundle();
11544                info.putString("shortMsg", shortMsg);
11545                info.putString("longMsg", longMsg);
11546                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
11547                Binder.restoreCallingIdentity(origId);
11548                return;
11549            }
11550
11551            // Log crash in battery stats.
11552            if (r != null) {
11553                mBatteryStatsService.noteProcessCrash(r.processName, r.uid);
11554            }
11555
11556            // If we can't identify the process or it's already exceeded its crash quota,
11557            // quit right away without showing a crash dialog.
11558            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
11559                Binder.restoreCallingIdentity(origId);
11560                return;
11561            }
11562
11563            Message msg = Message.obtain();
11564            msg.what = SHOW_ERROR_MSG;
11565            HashMap data = new HashMap();
11566            data.put("result", result);
11567            data.put("app", r);
11568            msg.obj = data;
11569            mHandler.sendMessage(msg);
11570
11571            Binder.restoreCallingIdentity(origId);
11572        }
11573
11574        int res = result.get();
11575
11576        Intent appErrorIntent = null;
11577        synchronized (this) {
11578            if (r != null && !r.isolated) {
11579                // XXX Can't keep track of crash time for isolated processes,
11580                // since they don't have a persistent identity.
11581                mProcessCrashTimes.put(r.info.processName, r.uid,
11582                        SystemClock.uptimeMillis());
11583            }
11584            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
11585                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
11586            }
11587        }
11588
11589        if (appErrorIntent != null) {
11590            try {
11591                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
11592            } catch (ActivityNotFoundException e) {
11593                Slog.w(TAG, "bug report receiver dissappeared", e);
11594            }
11595        }
11596    }
11597
11598    Intent createAppErrorIntentLocked(ProcessRecord r,
11599            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
11600        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
11601        if (report == null) {
11602            return null;
11603        }
11604        Intent result = new Intent(Intent.ACTION_APP_ERROR);
11605        result.setComponent(r.errorReportReceiver);
11606        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
11607        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
11608        return result;
11609    }
11610
11611    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
11612            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
11613        if (r.errorReportReceiver == null) {
11614            return null;
11615        }
11616
11617        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
11618            return null;
11619        }
11620
11621        ApplicationErrorReport report = new ApplicationErrorReport();
11622        report.packageName = r.info.packageName;
11623        report.installerPackageName = r.errorReportReceiver.getPackageName();
11624        report.processName = r.processName;
11625        report.time = timeMillis;
11626        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
11627
11628        if (r.crashing || r.forceCrashReport) {
11629            report.type = ApplicationErrorReport.TYPE_CRASH;
11630            report.crashInfo = crashInfo;
11631        } else if (r.notResponding) {
11632            report.type = ApplicationErrorReport.TYPE_ANR;
11633            report.anrInfo = new ApplicationErrorReport.AnrInfo();
11634
11635            report.anrInfo.activity = r.notRespondingReport.tag;
11636            report.anrInfo.cause = r.notRespondingReport.shortMsg;
11637            report.anrInfo.info = r.notRespondingReport.longMsg;
11638        }
11639
11640        return report;
11641    }
11642
11643    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
11644        enforceNotIsolatedCaller("getProcessesInErrorState");
11645        // assume our apps are happy - lazy create the list
11646        List<ActivityManager.ProcessErrorStateInfo> errList = null;
11647
11648        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
11649                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
11650        int userId = UserHandle.getUserId(Binder.getCallingUid());
11651
11652        synchronized (this) {
11653
11654            // iterate across all processes
11655            for (int i=mLruProcesses.size()-1; i>=0; i--) {
11656                ProcessRecord app = mLruProcesses.get(i);
11657                if (!allUsers && app.userId != userId) {
11658                    continue;
11659                }
11660                if ((app.thread != null) && (app.crashing || app.notResponding)) {
11661                    // This one's in trouble, so we'll generate a report for it
11662                    // crashes are higher priority (in case there's a crash *and* an anr)
11663                    ActivityManager.ProcessErrorStateInfo report = null;
11664                    if (app.crashing) {
11665                        report = app.crashingReport;
11666                    } else if (app.notResponding) {
11667                        report = app.notRespondingReport;
11668                    }
11669
11670                    if (report != null) {
11671                        if (errList == null) {
11672                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
11673                        }
11674                        errList.add(report);
11675                    } else {
11676                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
11677                                " crashing = " + app.crashing +
11678                                " notResponding = " + app.notResponding);
11679                    }
11680                }
11681            }
11682        }
11683
11684        return errList;
11685    }
11686
11687    static int procStateToImportance(int procState, int memAdj,
11688            ActivityManager.RunningAppProcessInfo currApp) {
11689        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
11690        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
11691            currApp.lru = memAdj;
11692        } else {
11693            currApp.lru = 0;
11694        }
11695        return imp;
11696    }
11697
11698    private void fillInProcMemInfo(ProcessRecord app,
11699            ActivityManager.RunningAppProcessInfo outInfo) {
11700        outInfo.pid = app.pid;
11701        outInfo.uid = app.info.uid;
11702        if (mHeavyWeightProcess == app) {
11703            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
11704        }
11705        if (app.persistent) {
11706            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
11707        }
11708        if (app.activities.size() > 0) {
11709            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
11710        }
11711        outInfo.lastTrimLevel = app.trimMemoryLevel;
11712        int adj = app.curAdj;
11713        int procState = app.curProcState;
11714        outInfo.importance = procStateToImportance(procState, adj, outInfo);
11715        outInfo.importanceReasonCode = app.adjTypeCode;
11716        outInfo.processState = app.curProcState;
11717    }
11718
11719    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
11720        enforceNotIsolatedCaller("getRunningAppProcesses");
11721        // Lazy instantiation of list
11722        List<ActivityManager.RunningAppProcessInfo> runList = null;
11723        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
11724                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
11725        int userId = UserHandle.getUserId(Binder.getCallingUid());
11726        synchronized (this) {
11727            // Iterate across all processes
11728            for (int i=mLruProcesses.size()-1; i>=0; i--) {
11729                ProcessRecord app = mLruProcesses.get(i);
11730                if (!allUsers && app.userId != userId) {
11731                    continue;
11732                }
11733                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
11734                    // Generate process state info for running application
11735                    ActivityManager.RunningAppProcessInfo currApp =
11736                        new ActivityManager.RunningAppProcessInfo(app.processName,
11737                                app.pid, app.getPackageList());
11738                    fillInProcMemInfo(app, currApp);
11739                    if (app.adjSource instanceof ProcessRecord) {
11740                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
11741                        currApp.importanceReasonImportance =
11742                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
11743                                        app.adjSourceProcState);
11744                    } else if (app.adjSource instanceof ActivityRecord) {
11745                        ActivityRecord r = (ActivityRecord)app.adjSource;
11746                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
11747                    }
11748                    if (app.adjTarget instanceof ComponentName) {
11749                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
11750                    }
11751                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
11752                    //        + " lru=" + currApp.lru);
11753                    if (runList == null) {
11754                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
11755                    }
11756                    runList.add(currApp);
11757                }
11758            }
11759        }
11760        return runList;
11761    }
11762
11763    public List<ApplicationInfo> getRunningExternalApplications() {
11764        enforceNotIsolatedCaller("getRunningExternalApplications");
11765        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
11766        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
11767        if (runningApps != null && runningApps.size() > 0) {
11768            Set<String> extList = new HashSet<String>();
11769            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
11770                if (app.pkgList != null) {
11771                    for (String pkg : app.pkgList) {
11772                        extList.add(pkg);
11773                    }
11774                }
11775            }
11776            IPackageManager pm = AppGlobals.getPackageManager();
11777            for (String pkg : extList) {
11778                try {
11779                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
11780                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
11781                        retList.add(info);
11782                    }
11783                } catch (RemoteException e) {
11784                }
11785            }
11786        }
11787        return retList;
11788    }
11789
11790    @Override
11791    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
11792        enforceNotIsolatedCaller("getMyMemoryState");
11793        synchronized (this) {
11794            ProcessRecord proc;
11795            synchronized (mPidsSelfLocked) {
11796                proc = mPidsSelfLocked.get(Binder.getCallingPid());
11797            }
11798            fillInProcMemInfo(proc, outInfo);
11799        }
11800    }
11801
11802    @Override
11803    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
11804        if (checkCallingPermission(android.Manifest.permission.DUMP)
11805                != PackageManager.PERMISSION_GRANTED) {
11806            pw.println("Permission Denial: can't dump ActivityManager from from pid="
11807                    + Binder.getCallingPid()
11808                    + ", uid=" + Binder.getCallingUid()
11809                    + " without permission "
11810                    + android.Manifest.permission.DUMP);
11811            return;
11812        }
11813
11814        boolean dumpAll = false;
11815        boolean dumpClient = false;
11816        String dumpPackage = null;
11817
11818        int opti = 0;
11819        while (opti < args.length) {
11820            String opt = args[opti];
11821            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
11822                break;
11823            }
11824            opti++;
11825            if ("-a".equals(opt)) {
11826                dumpAll = true;
11827            } else if ("-c".equals(opt)) {
11828                dumpClient = true;
11829            } else if ("-p".equals(opt)) {
11830                if (opti < args.length) {
11831                    dumpPackage = args[opti];
11832                    opti++;
11833                } else {
11834                    pw.println("Error: -p option requires package argument");
11835                    return;
11836                }
11837                dumpClient = true;
11838            } else if ("-h".equals(opt)) {
11839                pw.println("Activity manager dump options:");
11840                pw.println("  [-a] [-c] [-p package] [-h] [cmd] ...");
11841                pw.println("  cmd may be one of:");
11842                pw.println("    a[ctivities]: activity stack state");
11843                pw.println("    r[recents]: recent activities state");
11844                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
11845                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
11846                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
11847                pw.println("    o[om]: out of memory management");
11848                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
11849                pw.println("    provider [COMP_SPEC]: provider client-side state");
11850                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
11851                pw.println("    as[sociations]: tracked app associations");
11852                pw.println("    service [COMP_SPEC]: service client-side state");
11853                pw.println("    package [PACKAGE_NAME]: all state related to given package");
11854                pw.println("    all: dump all activities");
11855                pw.println("    top: dump the top activity");
11856                pw.println("    write: write all pending state to storage");
11857                pw.println("    track-associations: enable association tracking");
11858                pw.println("    untrack-associations: disable and clear association tracking");
11859                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
11860                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
11861                pw.println("    a partial substring in a component name, a");
11862                pw.println("    hex object identifier.");
11863                pw.println("  -a: include all available server state.");
11864                pw.println("  -c: include client state.");
11865                pw.println("  -p: limit output to given package.");
11866                return;
11867            } else {
11868                pw.println("Unknown argument: " + opt + "; use -h for help");
11869            }
11870        }
11871
11872        long origId = Binder.clearCallingIdentity();
11873        boolean more = false;
11874        // Is the caller requesting to dump a particular piece of data?
11875        if (opti < args.length) {
11876            String cmd = args[opti];
11877            opti++;
11878            if ("activities".equals(cmd) || "a".equals(cmd)) {
11879                synchronized (this) {
11880                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
11881                }
11882            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
11883                synchronized (this) {
11884                    dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
11885                }
11886            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
11887                String[] newArgs;
11888                String name;
11889                if (opti >= args.length) {
11890                    name = null;
11891                    newArgs = EMPTY_STRING_ARRAY;
11892                } else {
11893                    dumpPackage = args[opti];
11894                    opti++;
11895                    newArgs = new String[args.length - opti];
11896                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11897                            args.length - opti);
11898                }
11899                synchronized (this) {
11900                    dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
11901                }
11902            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
11903                String[] newArgs;
11904                String name;
11905                if (opti >= args.length) {
11906                    name = null;
11907                    newArgs = EMPTY_STRING_ARRAY;
11908                } else {
11909                    dumpPackage = args[opti];
11910                    opti++;
11911                    newArgs = new String[args.length - opti];
11912                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11913                            args.length - opti);
11914                }
11915                synchronized (this) {
11916                    dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
11917                }
11918            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
11919                String[] newArgs;
11920                String name;
11921                if (opti >= args.length) {
11922                    name = null;
11923                    newArgs = EMPTY_STRING_ARRAY;
11924                } else {
11925                    dumpPackage = args[opti];
11926                    opti++;
11927                    newArgs = new String[args.length - opti];
11928                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11929                            args.length - opti);
11930                }
11931                synchronized (this) {
11932                    dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
11933                }
11934            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
11935                synchronized (this) {
11936                    dumpOomLocked(fd, pw, args, opti, true);
11937                }
11938            } else if ("provider".equals(cmd)) {
11939                String[] newArgs;
11940                String name;
11941                if (opti >= args.length) {
11942                    name = null;
11943                    newArgs = EMPTY_STRING_ARRAY;
11944                } else {
11945                    name = args[opti];
11946                    opti++;
11947                    newArgs = new String[args.length - opti];
11948                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
11949                }
11950                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
11951                    pw.println("No providers match: " + name);
11952                    pw.println("Use -h for help.");
11953                }
11954            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
11955                synchronized (this) {
11956                    dumpProvidersLocked(fd, pw, args, opti, true, null);
11957                }
11958            } else if ("service".equals(cmd)) {
11959                String[] newArgs;
11960                String name;
11961                if (opti >= args.length) {
11962                    name = null;
11963                    newArgs = EMPTY_STRING_ARRAY;
11964                } else {
11965                    name = args[opti];
11966                    opti++;
11967                    newArgs = new String[args.length - opti];
11968                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11969                            args.length - opti);
11970                }
11971                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
11972                    pw.println("No services match: " + name);
11973                    pw.println("Use -h for help.");
11974                }
11975            } else if ("package".equals(cmd)) {
11976                String[] newArgs;
11977                if (opti >= args.length) {
11978                    pw.println("package: no package name specified");
11979                    pw.println("Use -h for help.");
11980                } else {
11981                    dumpPackage = args[opti];
11982                    opti++;
11983                    newArgs = new String[args.length - opti];
11984                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11985                            args.length - opti);
11986                    args = newArgs;
11987                    opti = 0;
11988                    more = true;
11989                }
11990            } else if ("associations".equals(cmd) || "as".equals(cmd)) {
11991                synchronized (this) {
11992                    dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
11993                }
11994            } else if ("services".equals(cmd) || "s".equals(cmd)) {
11995                synchronized (this) {
11996                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
11997                }
11998            } else if ("write".equals(cmd)) {
11999                mTaskPersister.flush();
12000                pw.println("All tasks persisted.");
12001                return;
12002            } else if ("track-associations".equals(cmd)) {
12003                synchronized (this) {
12004                    if (!mTrackingAssociations) {
12005                        mTrackingAssociations = true;
12006                        pw.println("Association tracking started.");
12007                    } else {
12008                        pw.println("Association tracking already enabled.");
12009                    }
12010                }
12011                return;
12012            } else if ("untrack-associations".equals(cmd)) {
12013                synchronized (this) {
12014                    if (mTrackingAssociations) {
12015                        mTrackingAssociations = false;
12016                        mAssociations.clear();
12017                        pw.println("Association tracking stopped.");
12018                    } else {
12019                        pw.println("Association tracking not running.");
12020                    }
12021                }
12022                return;
12023            } else {
12024                // Dumping a single activity?
12025                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
12026                    pw.println("Bad activity command, or no activities match: " + cmd);
12027                    pw.println("Use -h for help.");
12028                }
12029            }
12030            if (!more) {
12031                Binder.restoreCallingIdentity(origId);
12032                return;
12033            }
12034        }
12035
12036        // No piece of data specified, dump everything.
12037        synchronized (this) {
12038            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12039            pw.println();
12040            if (dumpAll) {
12041                pw.println("-------------------------------------------------------------------------------");
12042            }
12043            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12044            pw.println();
12045            if (dumpAll) {
12046                pw.println("-------------------------------------------------------------------------------");
12047            }
12048            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12049            pw.println();
12050            if (dumpAll) {
12051                pw.println("-------------------------------------------------------------------------------");
12052            }
12053            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12054            pw.println();
12055            if (dumpAll) {
12056                pw.println("-------------------------------------------------------------------------------");
12057            }
12058            dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12059            pw.println();
12060            if (dumpAll) {
12061                pw.println("-------------------------------------------------------------------------------");
12062            }
12063            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12064            if (mAssociations.size() > 0) {
12065                pw.println();
12066                if (dumpAll) {
12067                    pw.println("-------------------------------------------------------------------------------");
12068                }
12069                dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12070            }
12071            pw.println();
12072            if (dumpAll) {
12073                pw.println("-------------------------------------------------------------------------------");
12074            }
12075            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12076        }
12077        Binder.restoreCallingIdentity(origId);
12078    }
12079
12080    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12081            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
12082        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
12083
12084        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
12085                dumpPackage);
12086        boolean needSep = printedAnything;
12087
12088        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
12089                dumpPackage, needSep, "  mFocusedActivity: ");
12090        if (printed) {
12091            printedAnything = true;
12092            needSep = false;
12093        }
12094
12095        if (dumpPackage == null) {
12096            if (needSep) {
12097                pw.println();
12098            }
12099            needSep = true;
12100            printedAnything = true;
12101            mStackSupervisor.dump(pw, "  ");
12102        }
12103
12104        if (!printedAnything) {
12105            pw.println("  (nothing)");
12106        }
12107    }
12108
12109    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12110            int opti, boolean dumpAll, String dumpPackage) {
12111        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
12112
12113        boolean printedAnything = false;
12114
12115        if (mRecentTasks != null && mRecentTasks.size() > 0) {
12116            boolean printedHeader = false;
12117
12118            final int N = mRecentTasks.size();
12119            for (int i=0; i<N; i++) {
12120                TaskRecord tr = mRecentTasks.get(i);
12121                if (dumpPackage != null) {
12122                    if (tr.realActivity == null ||
12123                            !dumpPackage.equals(tr.realActivity)) {
12124                        continue;
12125                    }
12126                }
12127                if (!printedHeader) {
12128                    pw.println("  Recent tasks:");
12129                    printedHeader = true;
12130                    printedAnything = true;
12131                }
12132                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
12133                        pw.println(tr);
12134                if (dumpAll) {
12135                    mRecentTasks.get(i).dump(pw, "    ");
12136                }
12137            }
12138        }
12139
12140        if (!printedAnything) {
12141            pw.println("  (nothing)");
12142        }
12143    }
12144
12145    void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12146            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
12147        pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
12148
12149        int dumpUid = 0;
12150        if (dumpPackage != null) {
12151            IPackageManager pm = AppGlobals.getPackageManager();
12152            try {
12153                dumpUid = pm.getPackageUid(dumpPackage, 0);
12154            } catch (RemoteException e) {
12155            }
12156        }
12157
12158        boolean printedAnything = false;
12159
12160        final long now = SystemClock.uptimeMillis();
12161
12162        for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
12163            ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
12164                    = mAssociations.valueAt(i1);
12165            for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
12166                SparseArray<ArrayMap<String, Association>> sourceUids
12167                        = targetComponents.valueAt(i2);
12168                for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
12169                    ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
12170                    for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
12171                        Association ass = sourceProcesses.valueAt(i4);
12172                        if (dumpPackage != null) {
12173                            if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
12174                                    && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
12175                                continue;
12176                            }
12177                        }
12178                        printedAnything = true;
12179                        pw.print("  ");
12180                        pw.print(ass.mTargetProcess);
12181                        pw.print("/");
12182                        UserHandle.formatUid(pw, ass.mTargetUid);
12183                        pw.print(" <- ");
12184                        pw.print(ass.mSourceProcess);
12185                        pw.print("/");
12186                        UserHandle.formatUid(pw, ass.mSourceUid);
12187                        pw.println();
12188                        pw.print("    via ");
12189                        pw.print(ass.mTargetComponent.flattenToShortString());
12190                        pw.println();
12191                        pw.print("    ");
12192                        long dur = ass.mTime;
12193                        if (ass.mNesting > 0) {
12194                            dur += now - ass.mStartTime;
12195                        }
12196                        TimeUtils.formatDuration(dur, pw);
12197                        pw.print(" (");
12198                        pw.print(ass.mCount);
12199                        pw.println(" times)");
12200                        if (ass.mNesting > 0) {
12201                            pw.print("    ");
12202                            pw.print(" Currently active: ");
12203                            TimeUtils.formatDuration(now - ass.mStartTime, pw);
12204                            pw.println();
12205                        }
12206                    }
12207                }
12208            }
12209
12210        }
12211
12212        if (!printedAnything) {
12213            pw.println("  (nothing)");
12214        }
12215    }
12216
12217    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12218            int opti, boolean dumpAll, String dumpPackage) {
12219        boolean needSep = false;
12220        boolean printedAnything = false;
12221        int numPers = 0;
12222
12223        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
12224
12225        if (dumpAll) {
12226            final int NP = mProcessNames.getMap().size();
12227            for (int ip=0; ip<NP; ip++) {
12228                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
12229                final int NA = procs.size();
12230                for (int ia=0; ia<NA; ia++) {
12231                    ProcessRecord r = procs.valueAt(ia);
12232                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12233                        continue;
12234                    }
12235                    if (!needSep) {
12236                        pw.println("  All known processes:");
12237                        needSep = true;
12238                        printedAnything = true;
12239                    }
12240                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
12241                        pw.print(" UID "); pw.print(procs.keyAt(ia));
12242                        pw.print(" "); pw.println(r);
12243                    r.dump(pw, "    ");
12244                    if (r.persistent) {
12245                        numPers++;
12246                    }
12247                }
12248            }
12249        }
12250
12251        if (mIsolatedProcesses.size() > 0) {
12252            boolean printed = false;
12253            for (int i=0; i<mIsolatedProcesses.size(); i++) {
12254                ProcessRecord r = mIsolatedProcesses.valueAt(i);
12255                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12256                    continue;
12257                }
12258                if (!printed) {
12259                    if (needSep) {
12260                        pw.println();
12261                    }
12262                    pw.println("  Isolated process list (sorted by uid):");
12263                    printedAnything = true;
12264                    printed = true;
12265                    needSep = true;
12266                }
12267                pw.println(String.format("%sIsolated #%2d: %s",
12268                        "    ", i, r.toString()));
12269            }
12270        }
12271
12272        if (mLruProcesses.size() > 0) {
12273            if (needSep) {
12274                pw.println();
12275            }
12276            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
12277                    pw.print(" total, non-act at ");
12278                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12279                    pw.print(", non-svc at ");
12280                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12281                    pw.println("):");
12282            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
12283            needSep = true;
12284            printedAnything = true;
12285        }
12286
12287        if (dumpAll || dumpPackage != null) {
12288            synchronized (mPidsSelfLocked) {
12289                boolean printed = false;
12290                for (int i=0; i<mPidsSelfLocked.size(); i++) {
12291                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
12292                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12293                        continue;
12294                    }
12295                    if (!printed) {
12296                        if (needSep) pw.println();
12297                        needSep = true;
12298                        pw.println("  PID mappings:");
12299                        printed = true;
12300                        printedAnything = true;
12301                    }
12302                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
12303                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
12304                }
12305            }
12306        }
12307
12308        if (mForegroundProcesses.size() > 0) {
12309            synchronized (mPidsSelfLocked) {
12310                boolean printed = false;
12311                for (int i=0; i<mForegroundProcesses.size(); i++) {
12312                    ProcessRecord r = mPidsSelfLocked.get(
12313                            mForegroundProcesses.valueAt(i).pid);
12314                    if (dumpPackage != null && (r == null
12315                            || !r.pkgList.containsKey(dumpPackage))) {
12316                        continue;
12317                    }
12318                    if (!printed) {
12319                        if (needSep) pw.println();
12320                        needSep = true;
12321                        pw.println("  Foreground Processes:");
12322                        printed = true;
12323                        printedAnything = true;
12324                    }
12325                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
12326                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
12327                }
12328            }
12329        }
12330
12331        if (mPersistentStartingProcesses.size() > 0) {
12332            if (needSep) pw.println();
12333            needSep = true;
12334            printedAnything = true;
12335            pw.println("  Persisent processes that are starting:");
12336            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
12337                    "Starting Norm", "Restarting PERS", dumpPackage);
12338        }
12339
12340        if (mRemovedProcesses.size() > 0) {
12341            if (needSep) pw.println();
12342            needSep = true;
12343            printedAnything = true;
12344            pw.println("  Processes that are being removed:");
12345            dumpProcessList(pw, this, mRemovedProcesses, "    ",
12346                    "Removed Norm", "Removed PERS", dumpPackage);
12347        }
12348
12349        if (mProcessesOnHold.size() > 0) {
12350            if (needSep) pw.println();
12351            needSep = true;
12352            printedAnything = true;
12353            pw.println("  Processes that are on old until the system is ready:");
12354            dumpProcessList(pw, this, mProcessesOnHold, "    ",
12355                    "OnHold Norm", "OnHold PERS", dumpPackage);
12356        }
12357
12358        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
12359
12360        if (mProcessCrashTimes.getMap().size() > 0) {
12361            boolean printed = false;
12362            long now = SystemClock.uptimeMillis();
12363            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
12364            final int NP = pmap.size();
12365            for (int ip=0; ip<NP; ip++) {
12366                String pname = pmap.keyAt(ip);
12367                SparseArray<Long> uids = pmap.valueAt(ip);
12368                final int N = uids.size();
12369                for (int i=0; i<N; i++) {
12370                    int puid = uids.keyAt(i);
12371                    ProcessRecord r = mProcessNames.get(pname, puid);
12372                    if (dumpPackage != null && (r == null
12373                            || !r.pkgList.containsKey(dumpPackage))) {
12374                        continue;
12375                    }
12376                    if (!printed) {
12377                        if (needSep) pw.println();
12378                        needSep = true;
12379                        pw.println("  Time since processes crashed:");
12380                        printed = true;
12381                        printedAnything = true;
12382                    }
12383                    pw.print("    Process "); pw.print(pname);
12384                            pw.print(" uid "); pw.print(puid);
12385                            pw.print(": last crashed ");
12386                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
12387                            pw.println(" ago");
12388                }
12389            }
12390        }
12391
12392        if (mBadProcesses.getMap().size() > 0) {
12393            boolean printed = false;
12394            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
12395            final int NP = pmap.size();
12396            for (int ip=0; ip<NP; ip++) {
12397                String pname = pmap.keyAt(ip);
12398                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
12399                final int N = uids.size();
12400                for (int i=0; i<N; i++) {
12401                    int puid = uids.keyAt(i);
12402                    ProcessRecord r = mProcessNames.get(pname, puid);
12403                    if (dumpPackage != null && (r == null
12404                            || !r.pkgList.containsKey(dumpPackage))) {
12405                        continue;
12406                    }
12407                    if (!printed) {
12408                        if (needSep) pw.println();
12409                        needSep = true;
12410                        pw.println("  Bad processes:");
12411                        printedAnything = true;
12412                    }
12413                    BadProcessInfo info = uids.valueAt(i);
12414                    pw.print("    Bad process "); pw.print(pname);
12415                            pw.print(" uid "); pw.print(puid);
12416                            pw.print(": crashed at time "); pw.println(info.time);
12417                    if (info.shortMsg != null) {
12418                        pw.print("      Short msg: "); pw.println(info.shortMsg);
12419                    }
12420                    if (info.longMsg != null) {
12421                        pw.print("      Long msg: "); pw.println(info.longMsg);
12422                    }
12423                    if (info.stack != null) {
12424                        pw.println("      Stack:");
12425                        int lastPos = 0;
12426                        for (int pos=0; pos<info.stack.length(); pos++) {
12427                            if (info.stack.charAt(pos) == '\n') {
12428                                pw.print("        ");
12429                                pw.write(info.stack, lastPos, pos-lastPos);
12430                                pw.println();
12431                                lastPos = pos+1;
12432                            }
12433                        }
12434                        if (lastPos < info.stack.length()) {
12435                            pw.print("        ");
12436                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
12437                            pw.println();
12438                        }
12439                    }
12440                }
12441            }
12442        }
12443
12444        if (dumpPackage == null) {
12445            pw.println();
12446            needSep = false;
12447            pw.println("  mStartedUsers:");
12448            for (int i=0; i<mStartedUsers.size(); i++) {
12449                UserStartedState uss = mStartedUsers.valueAt(i);
12450                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
12451                        pw.print(": "); uss.dump("", pw);
12452            }
12453            pw.print("  mStartedUserArray: [");
12454            for (int i=0; i<mStartedUserArray.length; i++) {
12455                if (i > 0) pw.print(", ");
12456                pw.print(mStartedUserArray[i]);
12457            }
12458            pw.println("]");
12459            pw.print("  mUserLru: [");
12460            for (int i=0; i<mUserLru.size(); i++) {
12461                if (i > 0) pw.print(", ");
12462                pw.print(mUserLru.get(i));
12463            }
12464            pw.println("]");
12465            if (dumpAll) {
12466                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
12467            }
12468            synchronized (mUserProfileGroupIdsSelfLocked) {
12469                if (mUserProfileGroupIdsSelfLocked.size() > 0) {
12470                    pw.println("  mUserProfileGroupIds:");
12471                    for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
12472                        pw.print("    User #");
12473                        pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
12474                        pw.print(" -> profile #");
12475                        pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
12476                    }
12477                }
12478            }
12479        }
12480        if (mHomeProcess != null && (dumpPackage == null
12481                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
12482            if (needSep) {
12483                pw.println();
12484                needSep = false;
12485            }
12486            pw.println("  mHomeProcess: " + mHomeProcess);
12487        }
12488        if (mPreviousProcess != null && (dumpPackage == null
12489                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
12490            if (needSep) {
12491                pw.println();
12492                needSep = false;
12493            }
12494            pw.println("  mPreviousProcess: " + mPreviousProcess);
12495        }
12496        if (dumpAll) {
12497            StringBuilder sb = new StringBuilder(128);
12498            sb.append("  mPreviousProcessVisibleTime: ");
12499            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
12500            pw.println(sb);
12501        }
12502        if (mHeavyWeightProcess != null && (dumpPackage == null
12503                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
12504            if (needSep) {
12505                pw.println();
12506                needSep = false;
12507            }
12508            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12509        }
12510        if (dumpPackage == null) {
12511            pw.println("  mConfiguration: " + mConfiguration);
12512        }
12513        if (dumpAll) {
12514            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
12515            if (mCompatModePackages.getPackages().size() > 0) {
12516                boolean printed = false;
12517                for (Map.Entry<String, Integer> entry
12518                        : mCompatModePackages.getPackages().entrySet()) {
12519                    String pkg = entry.getKey();
12520                    int mode = entry.getValue();
12521                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
12522                        continue;
12523                    }
12524                    if (!printed) {
12525                        pw.println("  mScreenCompatPackages:");
12526                        printed = true;
12527                    }
12528                    pw.print("    "); pw.print(pkg); pw.print(": ");
12529                            pw.print(mode); pw.println();
12530                }
12531            }
12532        }
12533        if (dumpPackage == null) {
12534            pw.println("  mWakefulness="
12535                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
12536            pw.println("  mSleeping=" + mSleeping + " mLockScreenShown="
12537                    + lockScreenShownToString());
12538            pw.println("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice
12539                    + " mTestPssMode=" + mTestPssMode);
12540        }
12541        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
12542                || mOrigWaitForDebugger) {
12543            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
12544                    || dumpPackage.equals(mOrigDebugApp)) {
12545                if (needSep) {
12546                    pw.println();
12547                    needSep = false;
12548                }
12549                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
12550                        + " mDebugTransient=" + mDebugTransient
12551                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
12552            }
12553        }
12554        if (mOpenGlTraceApp != null) {
12555            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
12556                if (needSep) {
12557                    pw.println();
12558                    needSep = false;
12559                }
12560                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
12561            }
12562        }
12563        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
12564                || mProfileFd != null) {
12565            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
12566                if (needSep) {
12567                    pw.println();
12568                    needSep = false;
12569                }
12570                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
12571                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
12572                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
12573                        + mAutoStopProfiler);
12574                pw.println("  mProfileType=" + mProfileType);
12575            }
12576        }
12577        if (dumpPackage == null) {
12578            if (mAlwaysFinishActivities || mController != null) {
12579                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
12580                        + " mController=" + mController);
12581            }
12582            if (dumpAll) {
12583                pw.println("  Total persistent processes: " + numPers);
12584                pw.println("  mProcessesReady=" + mProcessesReady
12585                        + " mSystemReady=" + mSystemReady
12586                        + " mBooted=" + mBooted
12587                        + " mFactoryTest=" + mFactoryTest);
12588                pw.println("  mBooting=" + mBooting
12589                        + " mCallFinishBooting=" + mCallFinishBooting
12590                        + " mBootAnimationComplete=" + mBootAnimationComplete);
12591                pw.print("  mLastPowerCheckRealtime=");
12592                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
12593                        pw.println("");
12594                pw.print("  mLastPowerCheckUptime=");
12595                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
12596                        pw.println("");
12597                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
12598                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
12599                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
12600                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
12601                        + " (" + mLruProcesses.size() + " total)"
12602                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
12603                        + " mNumServiceProcs=" + mNumServiceProcs
12604                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
12605                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
12606                        + " mLastMemoryLevel" + mLastMemoryLevel
12607                        + " mLastNumProcesses" + mLastNumProcesses);
12608                long now = SystemClock.uptimeMillis();
12609                pw.print("  mLastIdleTime=");
12610                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
12611                        pw.print(" mLowRamSinceLastIdle=");
12612                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
12613                        pw.println();
12614            }
12615        }
12616
12617        if (!printedAnything) {
12618            pw.println("  (nothing)");
12619        }
12620    }
12621
12622    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
12623            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
12624        if (mProcessesToGc.size() > 0) {
12625            boolean printed = false;
12626            long now = SystemClock.uptimeMillis();
12627            for (int i=0; i<mProcessesToGc.size(); i++) {
12628                ProcessRecord proc = mProcessesToGc.get(i);
12629                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
12630                    continue;
12631                }
12632                if (!printed) {
12633                    if (needSep) pw.println();
12634                    needSep = true;
12635                    pw.println("  Processes that are waiting to GC:");
12636                    printed = true;
12637                }
12638                pw.print("    Process "); pw.println(proc);
12639                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
12640                        pw.print(", last gced=");
12641                        pw.print(now-proc.lastRequestedGc);
12642                        pw.print(" ms ago, last lowMem=");
12643                        pw.print(now-proc.lastLowMemory);
12644                        pw.println(" ms ago");
12645
12646            }
12647        }
12648        return needSep;
12649    }
12650
12651    void printOomLevel(PrintWriter pw, String name, int adj) {
12652        pw.print("    ");
12653        if (adj >= 0) {
12654            pw.print(' ');
12655            if (adj < 10) pw.print(' ');
12656        } else {
12657            if (adj > -10) pw.print(' ');
12658        }
12659        pw.print(adj);
12660        pw.print(": ");
12661        pw.print(name);
12662        pw.print(" (");
12663        pw.print(mProcessList.getMemLevel(adj)/1024);
12664        pw.println(" kB)");
12665    }
12666
12667    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12668            int opti, boolean dumpAll) {
12669        boolean needSep = false;
12670
12671        if (mLruProcesses.size() > 0) {
12672            if (needSep) pw.println();
12673            needSep = true;
12674            pw.println("  OOM levels:");
12675            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
12676            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
12677            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
12678            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
12679            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
12680            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
12681            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
12682            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
12683            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
12684            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
12685            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
12686            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
12687            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
12688            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
12689
12690            if (needSep) pw.println();
12691            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
12692                    pw.print(" total, non-act at ");
12693                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12694                    pw.print(", non-svc at ");
12695                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12696                    pw.println("):");
12697            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
12698            needSep = true;
12699        }
12700
12701        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
12702
12703        pw.println();
12704        pw.println("  mHomeProcess: " + mHomeProcess);
12705        pw.println("  mPreviousProcess: " + mPreviousProcess);
12706        if (mHeavyWeightProcess != null) {
12707            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12708        }
12709
12710        return true;
12711    }
12712
12713    /**
12714     * There are three ways to call this:
12715     *  - no provider specified: dump all the providers
12716     *  - a flattened component name that matched an existing provider was specified as the
12717     *    first arg: dump that one provider
12718     *  - the first arg isn't the flattened component name of an existing provider:
12719     *    dump all providers whose component contains the first arg as a substring
12720     */
12721    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
12722            int opti, boolean dumpAll) {
12723        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
12724    }
12725
12726    static class ItemMatcher {
12727        ArrayList<ComponentName> components;
12728        ArrayList<String> strings;
12729        ArrayList<Integer> objects;
12730        boolean all;
12731
12732        ItemMatcher() {
12733            all = true;
12734        }
12735
12736        void build(String name) {
12737            ComponentName componentName = ComponentName.unflattenFromString(name);
12738            if (componentName != null) {
12739                if (components == null) {
12740                    components = new ArrayList<ComponentName>();
12741                }
12742                components.add(componentName);
12743                all = false;
12744            } else {
12745                int objectId = 0;
12746                // Not a '/' separated full component name; maybe an object ID?
12747                try {
12748                    objectId = Integer.parseInt(name, 16);
12749                    if (objects == null) {
12750                        objects = new ArrayList<Integer>();
12751                    }
12752                    objects.add(objectId);
12753                    all = false;
12754                } catch (RuntimeException e) {
12755                    // Not an integer; just do string match.
12756                    if (strings == null) {
12757                        strings = new ArrayList<String>();
12758                    }
12759                    strings.add(name);
12760                    all = false;
12761                }
12762            }
12763        }
12764
12765        int build(String[] args, int opti) {
12766            for (; opti<args.length; opti++) {
12767                String name = args[opti];
12768                if ("--".equals(name)) {
12769                    return opti+1;
12770                }
12771                build(name);
12772            }
12773            return opti;
12774        }
12775
12776        boolean match(Object object, ComponentName comp) {
12777            if (all) {
12778                return true;
12779            }
12780            if (components != null) {
12781                for (int i=0; i<components.size(); i++) {
12782                    if (components.get(i).equals(comp)) {
12783                        return true;
12784                    }
12785                }
12786            }
12787            if (objects != null) {
12788                for (int i=0; i<objects.size(); i++) {
12789                    if (System.identityHashCode(object) == objects.get(i)) {
12790                        return true;
12791                    }
12792                }
12793            }
12794            if (strings != null) {
12795                String flat = comp.flattenToString();
12796                for (int i=0; i<strings.size(); i++) {
12797                    if (flat.contains(strings.get(i))) {
12798                        return true;
12799                    }
12800                }
12801            }
12802            return false;
12803        }
12804    }
12805
12806    /**
12807     * There are three things that cmd can be:
12808     *  - a flattened component name that matches an existing activity
12809     *  - the cmd arg isn't the flattened component name of an existing activity:
12810     *    dump all activity whose component contains the cmd as a substring
12811     *  - A hex number of the ActivityRecord object instance.
12812     */
12813    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
12814            int opti, boolean dumpAll) {
12815        ArrayList<ActivityRecord> activities;
12816
12817        synchronized (this) {
12818            activities = mStackSupervisor.getDumpActivitiesLocked(name);
12819        }
12820
12821        if (activities.size() <= 0) {
12822            return false;
12823        }
12824
12825        String[] newArgs = new String[args.length - opti];
12826        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12827
12828        TaskRecord lastTask = null;
12829        boolean needSep = false;
12830        for (int i=activities.size()-1; i>=0; i--) {
12831            ActivityRecord r = activities.get(i);
12832            if (needSep) {
12833                pw.println();
12834            }
12835            needSep = true;
12836            synchronized (this) {
12837                if (lastTask != r.task) {
12838                    lastTask = r.task;
12839                    pw.print("TASK "); pw.print(lastTask.affinity);
12840                            pw.print(" id="); pw.println(lastTask.taskId);
12841                    if (dumpAll) {
12842                        lastTask.dump(pw, "  ");
12843                    }
12844                }
12845            }
12846            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
12847        }
12848        return true;
12849    }
12850
12851    /**
12852     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
12853     * there is a thread associated with the activity.
12854     */
12855    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
12856            final ActivityRecord r, String[] args, boolean dumpAll) {
12857        String innerPrefix = prefix + "  ";
12858        synchronized (this) {
12859            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
12860                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
12861                    pw.print(" pid=");
12862                    if (r.app != null) pw.println(r.app.pid);
12863                    else pw.println("(not running)");
12864            if (dumpAll) {
12865                r.dump(pw, innerPrefix);
12866            }
12867        }
12868        if (r.app != null && r.app.thread != null) {
12869            // flush anything that is already in the PrintWriter since the thread is going
12870            // to write to the file descriptor directly
12871            pw.flush();
12872            try {
12873                TransferPipe tp = new TransferPipe();
12874                try {
12875                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
12876                            r.appToken, innerPrefix, args);
12877                    tp.go(fd);
12878                } finally {
12879                    tp.kill();
12880                }
12881            } catch (IOException e) {
12882                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
12883            } catch (RemoteException e) {
12884                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
12885            }
12886        }
12887    }
12888
12889    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12890            int opti, boolean dumpAll, String dumpPackage) {
12891        boolean needSep = false;
12892        boolean onlyHistory = false;
12893        boolean printedAnything = false;
12894
12895        if ("history".equals(dumpPackage)) {
12896            if (opti < args.length && "-s".equals(args[opti])) {
12897                dumpAll = false;
12898            }
12899            onlyHistory = true;
12900            dumpPackage = null;
12901        }
12902
12903        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
12904        if (!onlyHistory && dumpAll) {
12905            if (mRegisteredReceivers.size() > 0) {
12906                boolean printed = false;
12907                Iterator it = mRegisteredReceivers.values().iterator();
12908                while (it.hasNext()) {
12909                    ReceiverList r = (ReceiverList)it.next();
12910                    if (dumpPackage != null && (r.app == null ||
12911                            !dumpPackage.equals(r.app.info.packageName))) {
12912                        continue;
12913                    }
12914                    if (!printed) {
12915                        pw.println("  Registered Receivers:");
12916                        needSep = true;
12917                        printed = true;
12918                        printedAnything = true;
12919                    }
12920                    pw.print("  * "); pw.println(r);
12921                    r.dump(pw, "    ");
12922                }
12923            }
12924
12925            if (mReceiverResolver.dump(pw, needSep ?
12926                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
12927                    "    ", dumpPackage, false, false)) {
12928                needSep = true;
12929                printedAnything = true;
12930            }
12931        }
12932
12933        for (BroadcastQueue q : mBroadcastQueues) {
12934            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
12935            printedAnything |= needSep;
12936        }
12937
12938        needSep = true;
12939
12940        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
12941            for (int user=0; user<mStickyBroadcasts.size(); user++) {
12942                if (needSep) {
12943                    pw.println();
12944                }
12945                needSep = true;
12946                printedAnything = true;
12947                pw.print("  Sticky broadcasts for user ");
12948                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
12949                StringBuilder sb = new StringBuilder(128);
12950                for (Map.Entry<String, ArrayList<Intent>> ent
12951                        : mStickyBroadcasts.valueAt(user).entrySet()) {
12952                    pw.print("  * Sticky action "); pw.print(ent.getKey());
12953                    if (dumpAll) {
12954                        pw.println(":");
12955                        ArrayList<Intent> intents = ent.getValue();
12956                        final int N = intents.size();
12957                        for (int i=0; i<N; i++) {
12958                            sb.setLength(0);
12959                            sb.append("    Intent: ");
12960                            intents.get(i).toShortString(sb, false, true, false, false);
12961                            pw.println(sb.toString());
12962                            Bundle bundle = intents.get(i).getExtras();
12963                            if (bundle != null) {
12964                                pw.print("      ");
12965                                pw.println(bundle.toString());
12966                            }
12967                        }
12968                    } else {
12969                        pw.println("");
12970                    }
12971                }
12972            }
12973        }
12974
12975        if (!onlyHistory && dumpAll) {
12976            pw.println();
12977            for (BroadcastQueue queue : mBroadcastQueues) {
12978                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
12979                        + queue.mBroadcastsScheduled);
12980            }
12981            pw.println("  mHandler:");
12982            mHandler.dump(new PrintWriterPrinter(pw), "    ");
12983            needSep = true;
12984            printedAnything = true;
12985        }
12986
12987        if (!printedAnything) {
12988            pw.println("  (nothing)");
12989        }
12990    }
12991
12992    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12993            int opti, boolean dumpAll, String dumpPackage) {
12994        boolean needSep;
12995        boolean printedAnything = false;
12996
12997        ItemMatcher matcher = new ItemMatcher();
12998        matcher.build(args, opti);
12999
13000        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
13001
13002        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
13003        printedAnything |= needSep;
13004
13005        if (mLaunchingProviders.size() > 0) {
13006            boolean printed = false;
13007            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
13008                ContentProviderRecord r = mLaunchingProviders.get(i);
13009                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
13010                    continue;
13011                }
13012                if (!printed) {
13013                    if (needSep) pw.println();
13014                    needSep = true;
13015                    pw.println("  Launching content providers:");
13016                    printed = true;
13017                    printedAnything = true;
13018                }
13019                pw.print("  Launching #"); pw.print(i); pw.print(": ");
13020                        pw.println(r);
13021            }
13022        }
13023
13024        if (mGrantedUriPermissions.size() > 0) {
13025            boolean printed = false;
13026            int dumpUid = -2;
13027            if (dumpPackage != null) {
13028                try {
13029                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
13030                } catch (NameNotFoundException e) {
13031                    dumpUid = -1;
13032                }
13033            }
13034            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
13035                int uid = mGrantedUriPermissions.keyAt(i);
13036                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
13037                    continue;
13038                }
13039                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
13040                if (!printed) {
13041                    if (needSep) pw.println();
13042                    needSep = true;
13043                    pw.println("  Granted Uri Permissions:");
13044                    printed = true;
13045                    printedAnything = true;
13046                }
13047                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
13048                for (UriPermission perm : perms.values()) {
13049                    pw.print("    "); pw.println(perm);
13050                    if (dumpAll) {
13051                        perm.dump(pw, "      ");
13052                    }
13053                }
13054            }
13055        }
13056
13057        if (!printedAnything) {
13058            pw.println("  (nothing)");
13059        }
13060    }
13061
13062    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13063            int opti, boolean dumpAll, String dumpPackage) {
13064        boolean printed = false;
13065
13066        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
13067
13068        if (mIntentSenderRecords.size() > 0) {
13069            Iterator<WeakReference<PendingIntentRecord>> it
13070                    = mIntentSenderRecords.values().iterator();
13071            while (it.hasNext()) {
13072                WeakReference<PendingIntentRecord> ref = it.next();
13073                PendingIntentRecord rec = ref != null ? ref.get(): null;
13074                if (dumpPackage != null && (rec == null
13075                        || !dumpPackage.equals(rec.key.packageName))) {
13076                    continue;
13077                }
13078                printed = true;
13079                if (rec != null) {
13080                    pw.print("  * "); pw.println(rec);
13081                    if (dumpAll) {
13082                        rec.dump(pw, "    ");
13083                    }
13084                } else {
13085                    pw.print("  * "); pw.println(ref);
13086                }
13087            }
13088        }
13089
13090        if (!printed) {
13091            pw.println("  (nothing)");
13092        }
13093    }
13094
13095    private static final int dumpProcessList(PrintWriter pw,
13096            ActivityManagerService service, List list,
13097            String prefix, String normalLabel, String persistentLabel,
13098            String dumpPackage) {
13099        int numPers = 0;
13100        final int N = list.size()-1;
13101        for (int i=N; i>=0; i--) {
13102            ProcessRecord r = (ProcessRecord)list.get(i);
13103            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
13104                continue;
13105            }
13106            pw.println(String.format("%s%s #%2d: %s",
13107                    prefix, (r.persistent ? persistentLabel : normalLabel),
13108                    i, r.toString()));
13109            if (r.persistent) {
13110                numPers++;
13111            }
13112        }
13113        return numPers;
13114    }
13115
13116    private static final boolean dumpProcessOomList(PrintWriter pw,
13117            ActivityManagerService service, List<ProcessRecord> origList,
13118            String prefix, String normalLabel, String persistentLabel,
13119            boolean inclDetails, String dumpPackage) {
13120
13121        ArrayList<Pair<ProcessRecord, Integer>> list
13122                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
13123        for (int i=0; i<origList.size(); i++) {
13124            ProcessRecord r = origList.get(i);
13125            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13126                continue;
13127            }
13128            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
13129        }
13130
13131        if (list.size() <= 0) {
13132            return false;
13133        }
13134
13135        Comparator<Pair<ProcessRecord, Integer>> comparator
13136                = new Comparator<Pair<ProcessRecord, Integer>>() {
13137            @Override
13138            public int compare(Pair<ProcessRecord, Integer> object1,
13139                    Pair<ProcessRecord, Integer> object2) {
13140                if (object1.first.setAdj != object2.first.setAdj) {
13141                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
13142                }
13143                if (object1.second.intValue() != object2.second.intValue()) {
13144                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
13145                }
13146                return 0;
13147            }
13148        };
13149
13150        Collections.sort(list, comparator);
13151
13152        final long curRealtime = SystemClock.elapsedRealtime();
13153        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
13154        final long curUptime = SystemClock.uptimeMillis();
13155        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
13156
13157        for (int i=list.size()-1; i>=0; i--) {
13158            ProcessRecord r = list.get(i).first;
13159            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
13160            char schedGroup;
13161            switch (r.setSchedGroup) {
13162                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
13163                    schedGroup = 'B';
13164                    break;
13165                case Process.THREAD_GROUP_DEFAULT:
13166                    schedGroup = 'F';
13167                    break;
13168                default:
13169                    schedGroup = '?';
13170                    break;
13171            }
13172            char foreground;
13173            if (r.foregroundActivities) {
13174                foreground = 'A';
13175            } else if (r.foregroundServices) {
13176                foreground = 'S';
13177            } else {
13178                foreground = ' ';
13179            }
13180            String procState = ProcessList.makeProcStateString(r.curProcState);
13181            pw.print(prefix);
13182            pw.print(r.persistent ? persistentLabel : normalLabel);
13183            pw.print(" #");
13184            int num = (origList.size()-1)-list.get(i).second;
13185            if (num < 10) pw.print(' ');
13186            pw.print(num);
13187            pw.print(": ");
13188            pw.print(oomAdj);
13189            pw.print(' ');
13190            pw.print(schedGroup);
13191            pw.print('/');
13192            pw.print(foreground);
13193            pw.print('/');
13194            pw.print(procState);
13195            pw.print(" trm:");
13196            if (r.trimMemoryLevel < 10) pw.print(' ');
13197            pw.print(r.trimMemoryLevel);
13198            pw.print(' ');
13199            pw.print(r.toShortString());
13200            pw.print(" (");
13201            pw.print(r.adjType);
13202            pw.println(')');
13203            if (r.adjSource != null || r.adjTarget != null) {
13204                pw.print(prefix);
13205                pw.print("    ");
13206                if (r.adjTarget instanceof ComponentName) {
13207                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
13208                } else if (r.adjTarget != null) {
13209                    pw.print(r.adjTarget.toString());
13210                } else {
13211                    pw.print("{null}");
13212                }
13213                pw.print("<=");
13214                if (r.adjSource instanceof ProcessRecord) {
13215                    pw.print("Proc{");
13216                    pw.print(((ProcessRecord)r.adjSource).toShortString());
13217                    pw.println("}");
13218                } else if (r.adjSource != null) {
13219                    pw.println(r.adjSource.toString());
13220                } else {
13221                    pw.println("{null}");
13222                }
13223            }
13224            if (inclDetails) {
13225                pw.print(prefix);
13226                pw.print("    ");
13227                pw.print("oom: max="); pw.print(r.maxAdj);
13228                pw.print(" curRaw="); pw.print(r.curRawAdj);
13229                pw.print(" setRaw="); pw.print(r.setRawAdj);
13230                pw.print(" cur="); pw.print(r.curAdj);
13231                pw.print(" set="); pw.println(r.setAdj);
13232                pw.print(prefix);
13233                pw.print("    ");
13234                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
13235                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
13236                pw.print(" lastPss="); pw.print(r.lastPss);
13237                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
13238                pw.print(prefix);
13239                pw.print("    ");
13240                pw.print("cached="); pw.print(r.cached);
13241                pw.print(" empty="); pw.print(r.empty);
13242                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
13243
13244                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
13245                    if (r.lastWakeTime != 0) {
13246                        long wtime;
13247                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
13248                        synchronized (stats) {
13249                            wtime = stats.getProcessWakeTime(r.info.uid,
13250                                    r.pid, curRealtime);
13251                        }
13252                        long timeUsed = wtime - r.lastWakeTime;
13253                        pw.print(prefix);
13254                        pw.print("    ");
13255                        pw.print("keep awake over ");
13256                        TimeUtils.formatDuration(realtimeSince, pw);
13257                        pw.print(" used ");
13258                        TimeUtils.formatDuration(timeUsed, pw);
13259                        pw.print(" (");
13260                        pw.print((timeUsed*100)/realtimeSince);
13261                        pw.println("%)");
13262                    }
13263                    if (r.lastCpuTime != 0) {
13264                        long timeUsed = r.curCpuTime - r.lastCpuTime;
13265                        pw.print(prefix);
13266                        pw.print("    ");
13267                        pw.print("run cpu over ");
13268                        TimeUtils.formatDuration(uptimeSince, pw);
13269                        pw.print(" used ");
13270                        TimeUtils.formatDuration(timeUsed, pw);
13271                        pw.print(" (");
13272                        pw.print((timeUsed*100)/uptimeSince);
13273                        pw.println("%)");
13274                    }
13275                }
13276            }
13277        }
13278        return true;
13279    }
13280
13281    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
13282            String[] args) {
13283        ArrayList<ProcessRecord> procs;
13284        synchronized (this) {
13285            if (args != null && args.length > start
13286                    && args[start].charAt(0) != '-') {
13287                procs = new ArrayList<ProcessRecord>();
13288                int pid = -1;
13289                try {
13290                    pid = Integer.parseInt(args[start]);
13291                } catch (NumberFormatException e) {
13292                }
13293                for (int i=mLruProcesses.size()-1; i>=0; i--) {
13294                    ProcessRecord proc = mLruProcesses.get(i);
13295                    if (proc.pid == pid) {
13296                        procs.add(proc);
13297                    } else if (allPkgs && proc.pkgList != null
13298                            && proc.pkgList.containsKey(args[start])) {
13299                        procs.add(proc);
13300                    } else if (proc.processName.equals(args[start])) {
13301                        procs.add(proc);
13302                    }
13303                }
13304                if (procs.size() <= 0) {
13305                    return null;
13306                }
13307            } else {
13308                procs = new ArrayList<ProcessRecord>(mLruProcesses);
13309            }
13310        }
13311        return procs;
13312    }
13313
13314    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
13315            PrintWriter pw, String[] args) {
13316        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
13317        if (procs == null) {
13318            pw.println("No process found for: " + args[0]);
13319            return;
13320        }
13321
13322        long uptime = SystemClock.uptimeMillis();
13323        long realtime = SystemClock.elapsedRealtime();
13324        pw.println("Applications Graphics Acceleration Info:");
13325        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13326
13327        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13328            ProcessRecord r = procs.get(i);
13329            if (r.thread != null) {
13330                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
13331                pw.flush();
13332                try {
13333                    TransferPipe tp = new TransferPipe();
13334                    try {
13335                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
13336                        tp.go(fd);
13337                    } finally {
13338                        tp.kill();
13339                    }
13340                } catch (IOException e) {
13341                    pw.println("Failure while dumping the app: " + r);
13342                    pw.flush();
13343                } catch (RemoteException e) {
13344                    pw.println("Got a RemoteException while dumping the app " + r);
13345                    pw.flush();
13346                }
13347            }
13348        }
13349    }
13350
13351    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
13352        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
13353        if (procs == null) {
13354            pw.println("No process found for: " + args[0]);
13355            return;
13356        }
13357
13358        pw.println("Applications Database Info:");
13359
13360        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13361            ProcessRecord r = procs.get(i);
13362            if (r.thread != null) {
13363                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
13364                pw.flush();
13365                try {
13366                    TransferPipe tp = new TransferPipe();
13367                    try {
13368                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
13369                        tp.go(fd);
13370                    } finally {
13371                        tp.kill();
13372                    }
13373                } catch (IOException e) {
13374                    pw.println("Failure while dumping the app: " + r);
13375                    pw.flush();
13376                } catch (RemoteException e) {
13377                    pw.println("Got a RemoteException while dumping the app " + r);
13378                    pw.flush();
13379                }
13380            }
13381        }
13382    }
13383
13384    final static class MemItem {
13385        final boolean isProc;
13386        final String label;
13387        final String shortLabel;
13388        final long pss;
13389        final int id;
13390        final boolean hasActivities;
13391        ArrayList<MemItem> subitems;
13392
13393        public MemItem(String _label, String _shortLabel, long _pss, int _id,
13394                boolean _hasActivities) {
13395            isProc = true;
13396            label = _label;
13397            shortLabel = _shortLabel;
13398            pss = _pss;
13399            id = _id;
13400            hasActivities = _hasActivities;
13401        }
13402
13403        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
13404            isProc = false;
13405            label = _label;
13406            shortLabel = _shortLabel;
13407            pss = _pss;
13408            id = _id;
13409            hasActivities = false;
13410        }
13411    }
13412
13413    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
13414            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
13415        if (sort && !isCompact) {
13416            Collections.sort(items, new Comparator<MemItem>() {
13417                @Override
13418                public int compare(MemItem lhs, MemItem rhs) {
13419                    if (lhs.pss < rhs.pss) {
13420                        return 1;
13421                    } else if (lhs.pss > rhs.pss) {
13422                        return -1;
13423                    }
13424                    return 0;
13425                }
13426            });
13427        }
13428
13429        for (int i=0; i<items.size(); i++) {
13430            MemItem mi = items.get(i);
13431            if (!isCompact) {
13432                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
13433            } else if (mi.isProc) {
13434                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
13435                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
13436                pw.println(mi.hasActivities ? ",a" : ",e");
13437            } else {
13438                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
13439                pw.println(mi.pss);
13440            }
13441            if (mi.subitems != null) {
13442                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
13443                        true, isCompact);
13444            }
13445        }
13446    }
13447
13448    // These are in KB.
13449    static final long[] DUMP_MEM_BUCKETS = new long[] {
13450        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
13451        120*1024, 160*1024, 200*1024,
13452        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
13453        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
13454    };
13455
13456    static final void appendMemBucket(StringBuilder out, long memKB, String label,
13457            boolean stackLike) {
13458        int start = label.lastIndexOf('.');
13459        if (start >= 0) start++;
13460        else start = 0;
13461        int end = label.length();
13462        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
13463            if (DUMP_MEM_BUCKETS[i] >= memKB) {
13464                long bucket = DUMP_MEM_BUCKETS[i]/1024;
13465                out.append(bucket);
13466                out.append(stackLike ? "MB." : "MB ");
13467                out.append(label, start, end);
13468                return;
13469            }
13470        }
13471        out.append(memKB/1024);
13472        out.append(stackLike ? "MB." : "MB ");
13473        out.append(label, start, end);
13474    }
13475
13476    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
13477            ProcessList.NATIVE_ADJ,
13478            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
13479            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
13480            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
13481            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
13482            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
13483            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
13484    };
13485    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
13486            "Native",
13487            "System", "Persistent", "Persistent Service", "Foreground",
13488            "Visible", "Perceptible",
13489            "Heavy Weight", "Backup",
13490            "A Services", "Home",
13491            "Previous", "B Services", "Cached"
13492    };
13493    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
13494            "native",
13495            "sys", "pers", "persvc", "fore",
13496            "vis", "percept",
13497            "heavy", "backup",
13498            "servicea", "home",
13499            "prev", "serviceb", "cached"
13500    };
13501
13502    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
13503            long realtime, boolean isCheckinRequest, boolean isCompact) {
13504        if (isCheckinRequest || isCompact) {
13505            // short checkin version
13506            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
13507        } else {
13508            pw.println("Applications Memory Usage (kB):");
13509            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13510        }
13511    }
13512
13513    private static final int KSM_SHARED = 0;
13514    private static final int KSM_SHARING = 1;
13515    private static final int KSM_UNSHARED = 2;
13516    private static final int KSM_VOLATILE = 3;
13517
13518    private final long[] getKsmInfo() {
13519        long[] longOut = new long[4];
13520        final int[] SINGLE_LONG_FORMAT = new int[] {
13521            Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
13522        };
13523        long[] longTmp = new long[1];
13524        Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
13525                SINGLE_LONG_FORMAT, null, longTmp, null);
13526        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
13527        longTmp[0] = 0;
13528        Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
13529                SINGLE_LONG_FORMAT, null, longTmp, null);
13530        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
13531        longTmp[0] = 0;
13532        Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
13533                SINGLE_LONG_FORMAT, null, longTmp, null);
13534        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
13535        longTmp[0] = 0;
13536        Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
13537                SINGLE_LONG_FORMAT, null, longTmp, null);
13538        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
13539        return longOut;
13540    }
13541
13542    final void dumpApplicationMemoryUsage(FileDescriptor fd,
13543            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
13544        boolean dumpDetails = false;
13545        boolean dumpFullDetails = false;
13546        boolean dumpDalvik = false;
13547        boolean oomOnly = false;
13548        boolean isCompact = false;
13549        boolean localOnly = false;
13550        boolean packages = false;
13551
13552        int opti = 0;
13553        while (opti < args.length) {
13554            String opt = args[opti];
13555            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13556                break;
13557            }
13558            opti++;
13559            if ("-a".equals(opt)) {
13560                dumpDetails = true;
13561                dumpFullDetails = true;
13562                dumpDalvik = true;
13563            } else if ("-d".equals(opt)) {
13564                dumpDalvik = true;
13565            } else if ("-c".equals(opt)) {
13566                isCompact = true;
13567            } else if ("--oom".equals(opt)) {
13568                oomOnly = true;
13569            } else if ("--local".equals(opt)) {
13570                localOnly = true;
13571            } else if ("--package".equals(opt)) {
13572                packages = true;
13573            } else if ("-h".equals(opt)) {
13574                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
13575                pw.println("  -a: include all available information for each process.");
13576                pw.println("  -d: include dalvik details when dumping process details.");
13577                pw.println("  -c: dump in a compact machine-parseable representation.");
13578                pw.println("  --oom: only show processes organized by oom adj.");
13579                pw.println("  --local: only collect details locally, don't call process.");
13580                pw.println("  --package: interpret process arg as package, dumping all");
13581                pw.println("             processes that have loaded that package.");
13582                pw.println("If [process] is specified it can be the name or ");
13583                pw.println("pid of a specific process to dump.");
13584                return;
13585            } else {
13586                pw.println("Unknown argument: " + opt + "; use -h for help");
13587            }
13588        }
13589
13590        final boolean isCheckinRequest = scanArgs(args, "--checkin");
13591        long uptime = SystemClock.uptimeMillis();
13592        long realtime = SystemClock.elapsedRealtime();
13593        final long[] tmpLong = new long[1];
13594
13595        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
13596        if (procs == null) {
13597            // No Java processes.  Maybe they want to print a native process.
13598            if (args != null && args.length > opti
13599                    && args[opti].charAt(0) != '-') {
13600                ArrayList<ProcessCpuTracker.Stats> nativeProcs
13601                        = new ArrayList<ProcessCpuTracker.Stats>();
13602                updateCpuStatsNow();
13603                int findPid = -1;
13604                try {
13605                    findPid = Integer.parseInt(args[opti]);
13606                } catch (NumberFormatException e) {
13607                }
13608                synchronized (mProcessCpuTracker) {
13609                    final int N = mProcessCpuTracker.countStats();
13610                    for (int i=0; i<N; i++) {
13611                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
13612                        if (st.pid == findPid || (st.baseName != null
13613                                && st.baseName.equals(args[opti]))) {
13614                            nativeProcs.add(st);
13615                        }
13616                    }
13617                }
13618                if (nativeProcs.size() > 0) {
13619                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
13620                            isCompact);
13621                    Debug.MemoryInfo mi = null;
13622                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
13623                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
13624                        final int pid = r.pid;
13625                        if (!isCheckinRequest && dumpDetails) {
13626                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
13627                        }
13628                        if (mi == null) {
13629                            mi = new Debug.MemoryInfo();
13630                        }
13631                        if (dumpDetails || (!brief && !oomOnly)) {
13632                            Debug.getMemoryInfo(pid, mi);
13633                        } else {
13634                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
13635                            mi.dalvikPrivateDirty = (int)tmpLong[0];
13636                        }
13637                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
13638                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
13639                        if (isCheckinRequest) {
13640                            pw.println();
13641                        }
13642                    }
13643                    return;
13644                }
13645            }
13646            pw.println("No process found for: " + args[opti]);
13647            return;
13648        }
13649
13650        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
13651            dumpDetails = true;
13652        }
13653
13654        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
13655
13656        String[] innerArgs = new String[args.length-opti];
13657        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
13658
13659        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
13660        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
13661        long nativePss = 0;
13662        long dalvikPss = 0;
13663        long otherPss = 0;
13664        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
13665
13666        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
13667        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
13668                new ArrayList[DUMP_MEM_OOM_LABEL.length];
13669
13670        long totalPss = 0;
13671        long cachedPss = 0;
13672
13673        Debug.MemoryInfo mi = null;
13674        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13675            final ProcessRecord r = procs.get(i);
13676            final IApplicationThread thread;
13677            final int pid;
13678            final int oomAdj;
13679            final boolean hasActivities;
13680            synchronized (this) {
13681                thread = r.thread;
13682                pid = r.pid;
13683                oomAdj = r.getSetAdjWithServices();
13684                hasActivities = r.activities.size() > 0;
13685            }
13686            if (thread != null) {
13687                if (!isCheckinRequest && dumpDetails) {
13688                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
13689                }
13690                if (mi == null) {
13691                    mi = new Debug.MemoryInfo();
13692                }
13693                if (dumpDetails || (!brief && !oomOnly)) {
13694                    Debug.getMemoryInfo(pid, mi);
13695                } else {
13696                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
13697                    mi.dalvikPrivateDirty = (int)tmpLong[0];
13698                }
13699                if (dumpDetails) {
13700                    if (localOnly) {
13701                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
13702                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
13703                        if (isCheckinRequest) {
13704                            pw.println();
13705                        }
13706                    } else {
13707                        try {
13708                            pw.flush();
13709                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
13710                                    dumpDalvik, innerArgs);
13711                        } catch (RemoteException e) {
13712                            if (!isCheckinRequest) {
13713                                pw.println("Got RemoteException!");
13714                                pw.flush();
13715                            }
13716                        }
13717                    }
13718                }
13719
13720                final long myTotalPss = mi.getTotalPss();
13721                final long myTotalUss = mi.getTotalUss();
13722
13723                synchronized (this) {
13724                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
13725                        // Record this for posterity if the process has been stable.
13726                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
13727                    }
13728                }
13729
13730                if (!isCheckinRequest && mi != null) {
13731                    totalPss += myTotalPss;
13732                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
13733                            (hasActivities ? " / activities)" : ")"),
13734                            r.processName, myTotalPss, pid, hasActivities);
13735                    procMems.add(pssItem);
13736                    procMemsMap.put(pid, pssItem);
13737
13738                    nativePss += mi.nativePss;
13739                    dalvikPss += mi.dalvikPss;
13740                    otherPss += mi.otherPss;
13741                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13742                        long mem = mi.getOtherPss(j);
13743                        miscPss[j] += mem;
13744                        otherPss -= mem;
13745                    }
13746
13747                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
13748                        cachedPss += myTotalPss;
13749                    }
13750
13751                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
13752                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
13753                                || oomIndex == (oomPss.length-1)) {
13754                            oomPss[oomIndex] += myTotalPss;
13755                            if (oomProcs[oomIndex] == null) {
13756                                oomProcs[oomIndex] = new ArrayList<MemItem>();
13757                            }
13758                            oomProcs[oomIndex].add(pssItem);
13759                            break;
13760                        }
13761                    }
13762                }
13763            }
13764        }
13765
13766        long nativeProcTotalPss = 0;
13767
13768        if (!isCheckinRequest && procs.size() > 1 && !packages) {
13769            // If we are showing aggregations, also look for native processes to
13770            // include so that our aggregations are more accurate.
13771            updateCpuStatsNow();
13772            mi = null;
13773            synchronized (mProcessCpuTracker) {
13774                final int N = mProcessCpuTracker.countStats();
13775                for (int i=0; i<N; i++) {
13776                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
13777                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
13778                        if (mi == null) {
13779                            mi = new Debug.MemoryInfo();
13780                        }
13781                        if (!brief && !oomOnly) {
13782                            Debug.getMemoryInfo(st.pid, mi);
13783                        } else {
13784                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
13785                            mi.nativePrivateDirty = (int)tmpLong[0];
13786                        }
13787
13788                        final long myTotalPss = mi.getTotalPss();
13789                        totalPss += myTotalPss;
13790                        nativeProcTotalPss += myTotalPss;
13791
13792                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
13793                                st.name, myTotalPss, st.pid, false);
13794                        procMems.add(pssItem);
13795
13796                        nativePss += mi.nativePss;
13797                        dalvikPss += mi.dalvikPss;
13798                        otherPss += mi.otherPss;
13799                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13800                            long mem = mi.getOtherPss(j);
13801                            miscPss[j] += mem;
13802                            otherPss -= mem;
13803                        }
13804                        oomPss[0] += myTotalPss;
13805                        if (oomProcs[0] == null) {
13806                            oomProcs[0] = new ArrayList<MemItem>();
13807                        }
13808                        oomProcs[0].add(pssItem);
13809                    }
13810                }
13811            }
13812
13813            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
13814
13815            catMems.add(new MemItem("Native", "Native", nativePss, -1));
13816            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
13817            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
13818            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13819                String label = Debug.MemoryInfo.getOtherLabel(j);
13820                catMems.add(new MemItem(label, label, miscPss[j], j));
13821            }
13822
13823            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
13824            for (int j=0; j<oomPss.length; j++) {
13825                if (oomPss[j] != 0) {
13826                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
13827                            : DUMP_MEM_OOM_LABEL[j];
13828                    MemItem item = new MemItem(label, label, oomPss[j],
13829                            DUMP_MEM_OOM_ADJ[j]);
13830                    item.subitems = oomProcs[j];
13831                    oomMems.add(item);
13832                }
13833            }
13834
13835            if (!brief && !oomOnly && !isCompact) {
13836                pw.println();
13837                pw.println("Total PSS by process:");
13838                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
13839                pw.println();
13840            }
13841            if (!isCompact) {
13842                pw.println("Total PSS by OOM adjustment:");
13843            }
13844            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
13845            if (!brief && !oomOnly) {
13846                PrintWriter out = categoryPw != null ? categoryPw : pw;
13847                if (!isCompact) {
13848                    out.println();
13849                    out.println("Total PSS by category:");
13850                }
13851                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
13852            }
13853            if (!isCompact) {
13854                pw.println();
13855            }
13856            MemInfoReader memInfo = new MemInfoReader();
13857            memInfo.readMemInfo();
13858            if (nativeProcTotalPss > 0) {
13859                synchronized (this) {
13860                    mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
13861                            memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
13862                            memInfo.getKernelUsedSizeKb(), nativeProcTotalPss);
13863                }
13864            }
13865            if (!brief) {
13866                if (!isCompact) {
13867                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
13868                    pw.print(" kB (status ");
13869                    switch (mLastMemoryLevel) {
13870                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
13871                            pw.println("normal)");
13872                            break;
13873                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
13874                            pw.println("moderate)");
13875                            break;
13876                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
13877                            pw.println("low)");
13878                            break;
13879                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
13880                            pw.println("critical)");
13881                            break;
13882                        default:
13883                            pw.print(mLastMemoryLevel);
13884                            pw.println(")");
13885                            break;
13886                    }
13887                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
13888                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
13889                            pw.print(cachedPss); pw.print(" cached pss + ");
13890                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached kernel + ");
13891                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
13892                } else {
13893                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
13894                    pw.print(cachedPss + memInfo.getCachedSizeKb()
13895                            + memInfo.getFreeSizeKb()); pw.print(",");
13896                    pw.println(totalPss - cachedPss);
13897                }
13898            }
13899            if (!isCompact) {
13900                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
13901                        + memInfo.getKernelUsedSizeKb()); pw.print(" kB (");
13902                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
13903                        pw.print(memInfo.getKernelUsedSizeKb()); pw.print(" kernel)\n");
13904                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
13905                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
13906                        - memInfo.getKernelUsedSizeKb()); pw.println(" kB");
13907            }
13908            if (!brief) {
13909                if (memInfo.getZramTotalSizeKb() != 0) {
13910                    if (!isCompact) {
13911                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
13912                                pw.print(" kB physical used for ");
13913                                pw.print(memInfo.getSwapTotalSizeKb()
13914                                        - memInfo.getSwapFreeSizeKb());
13915                                pw.print(" kB in swap (");
13916                                pw.print(memInfo.getSwapTotalSizeKb());
13917                                pw.println(" kB total swap)");
13918                    } else {
13919                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
13920                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
13921                                pw.println(memInfo.getSwapFreeSizeKb());
13922                    }
13923                }
13924                final long[] ksm = getKsmInfo();
13925                if (!isCompact) {
13926                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
13927                            || ksm[KSM_VOLATILE] != 0) {
13928                        pw.print("      KSM: "); pw.print(ksm[KSM_SHARING]);
13929                                pw.print(" kB saved from shared ");
13930                                pw.print(ksm[KSM_SHARED]); pw.println(" kB");
13931                        pw.print("           "); pw.print(ksm[KSM_UNSHARED]);
13932                                pw.print(" kB unshared; ");
13933                                pw.print(ksm[KSM_VOLATILE]); pw.println(" kB volatile");
13934                    }
13935                    pw.print("   Tuning: ");
13936                    pw.print(ActivityManager.staticGetMemoryClass());
13937                    pw.print(" (large ");
13938                    pw.print(ActivityManager.staticGetLargeMemoryClass());
13939                    pw.print("), oom ");
13940                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
13941                    pw.print(" kB");
13942                    pw.print(", restore limit ");
13943                    pw.print(mProcessList.getCachedRestoreThresholdKb());
13944                    pw.print(" kB");
13945                    if (ActivityManager.isLowRamDeviceStatic()) {
13946                        pw.print(" (low-ram)");
13947                    }
13948                    if (ActivityManager.isHighEndGfx()) {
13949                        pw.print(" (high-end-gfx)");
13950                    }
13951                    pw.println();
13952                } else {
13953                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
13954                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
13955                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
13956                    pw.print("tuning,");
13957                    pw.print(ActivityManager.staticGetMemoryClass());
13958                    pw.print(',');
13959                    pw.print(ActivityManager.staticGetLargeMemoryClass());
13960                    pw.print(',');
13961                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
13962                    if (ActivityManager.isLowRamDeviceStatic()) {
13963                        pw.print(",low-ram");
13964                    }
13965                    if (ActivityManager.isHighEndGfx()) {
13966                        pw.print(",high-end-gfx");
13967                    }
13968                    pw.println();
13969                }
13970            }
13971        }
13972    }
13973
13974    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
13975            long memtrack, String name) {
13976        sb.append("  ");
13977        sb.append(ProcessList.makeOomAdjString(oomAdj));
13978        sb.append(' ');
13979        sb.append(ProcessList.makeProcStateString(procState));
13980        sb.append(' ');
13981        ProcessList.appendRamKb(sb, pss);
13982        sb.append(" kB: ");
13983        sb.append(name);
13984        if (memtrack > 0) {
13985            sb.append(" (");
13986            sb.append(memtrack);
13987            sb.append(" kB memtrack)");
13988        }
13989    }
13990
13991    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
13992        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
13993        sb.append(" (pid ");
13994        sb.append(mi.pid);
13995        sb.append(") ");
13996        sb.append(mi.adjType);
13997        sb.append('\n');
13998        if (mi.adjReason != null) {
13999            sb.append("                      ");
14000            sb.append(mi.adjReason);
14001            sb.append('\n');
14002        }
14003    }
14004
14005    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
14006        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
14007        for (int i=0, N=memInfos.size(); i<N; i++) {
14008            ProcessMemInfo mi = memInfos.get(i);
14009            infoMap.put(mi.pid, mi);
14010        }
14011        updateCpuStatsNow();
14012        long[] memtrackTmp = new long[1];
14013        synchronized (mProcessCpuTracker) {
14014            final int N = mProcessCpuTracker.countStats();
14015            for (int i=0; i<N; i++) {
14016                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14017                if (st.vsize > 0) {
14018                    long pss = Debug.getPss(st.pid, null, memtrackTmp);
14019                    if (pss > 0) {
14020                        if (infoMap.indexOfKey(st.pid) < 0) {
14021                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
14022                                    ProcessList.NATIVE_ADJ, -1, "native", null);
14023                            mi.pss = pss;
14024                            mi.memtrack = memtrackTmp[0];
14025                            memInfos.add(mi);
14026                        }
14027                    }
14028                }
14029            }
14030        }
14031
14032        long totalPss = 0;
14033        long totalMemtrack = 0;
14034        for (int i=0, N=memInfos.size(); i<N; i++) {
14035            ProcessMemInfo mi = memInfos.get(i);
14036            if (mi.pss == 0) {
14037                mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
14038                mi.memtrack = memtrackTmp[0];
14039            }
14040            totalPss += mi.pss;
14041            totalMemtrack += mi.memtrack;
14042        }
14043        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
14044            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
14045                if (lhs.oomAdj != rhs.oomAdj) {
14046                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
14047                }
14048                if (lhs.pss != rhs.pss) {
14049                    return lhs.pss < rhs.pss ? 1 : -1;
14050                }
14051                return 0;
14052            }
14053        });
14054
14055        StringBuilder tag = new StringBuilder(128);
14056        StringBuilder stack = new StringBuilder(128);
14057        tag.append("Low on memory -- ");
14058        appendMemBucket(tag, totalPss, "total", false);
14059        appendMemBucket(stack, totalPss, "total", true);
14060
14061        StringBuilder fullNativeBuilder = new StringBuilder(1024);
14062        StringBuilder shortNativeBuilder = new StringBuilder(1024);
14063        StringBuilder fullJavaBuilder = new StringBuilder(1024);
14064
14065        boolean firstLine = true;
14066        int lastOomAdj = Integer.MIN_VALUE;
14067        long extraNativeRam = 0;
14068        long extraNativeMemtrack = 0;
14069        long cachedPss = 0;
14070        for (int i=0, N=memInfos.size(); i<N; i++) {
14071            ProcessMemInfo mi = memInfos.get(i);
14072
14073            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
14074                cachedPss += mi.pss;
14075            }
14076
14077            if (mi.oomAdj != ProcessList.NATIVE_ADJ
14078                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
14079                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
14080                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
14081                if (lastOomAdj != mi.oomAdj) {
14082                    lastOomAdj = mi.oomAdj;
14083                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14084                        tag.append(" / ");
14085                    }
14086                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
14087                        if (firstLine) {
14088                            stack.append(":");
14089                            firstLine = false;
14090                        }
14091                        stack.append("\n\t at ");
14092                    } else {
14093                        stack.append("$");
14094                    }
14095                } else {
14096                    tag.append(" ");
14097                    stack.append("$");
14098                }
14099                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14100                    appendMemBucket(tag, mi.pss, mi.name, false);
14101                }
14102                appendMemBucket(stack, mi.pss, mi.name, true);
14103                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
14104                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
14105                    stack.append("(");
14106                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
14107                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
14108                            stack.append(DUMP_MEM_OOM_LABEL[k]);
14109                            stack.append(":");
14110                            stack.append(DUMP_MEM_OOM_ADJ[k]);
14111                        }
14112                    }
14113                    stack.append(")");
14114                }
14115            }
14116
14117            appendMemInfo(fullNativeBuilder, mi);
14118            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
14119                // The short form only has native processes that are >= 512K.
14120                if (mi.pss >= 512) {
14121                    appendMemInfo(shortNativeBuilder, mi);
14122                } else {
14123                    extraNativeRam += mi.pss;
14124                    extraNativeMemtrack += mi.memtrack;
14125                }
14126            } else {
14127                // Short form has all other details, but if we have collected RAM
14128                // from smaller native processes let's dump a summary of that.
14129                if (extraNativeRam > 0) {
14130                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
14131                            -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
14132                    shortNativeBuilder.append('\n');
14133                    extraNativeRam = 0;
14134                }
14135                appendMemInfo(fullJavaBuilder, mi);
14136            }
14137        }
14138
14139        fullJavaBuilder.append("           ");
14140        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
14141        fullJavaBuilder.append(" kB: TOTAL");
14142        if (totalMemtrack > 0) {
14143            fullJavaBuilder.append(" (");
14144            fullJavaBuilder.append(totalMemtrack);
14145            fullJavaBuilder.append(" kB memtrack)");
14146        } else {
14147        }
14148        fullJavaBuilder.append("\n");
14149
14150        MemInfoReader memInfo = new MemInfoReader();
14151        memInfo.readMemInfo();
14152        final long[] infos = memInfo.getRawInfo();
14153
14154        StringBuilder memInfoBuilder = new StringBuilder(1024);
14155        Debug.getMemInfo(infos);
14156        memInfoBuilder.append("  MemInfo: ");
14157        memInfoBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
14158        memInfoBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
14159        memInfoBuilder.append(infos[Debug.MEMINFO_VM_ALLOC_USED]).append(" kB vm alloc, ");
14160        memInfoBuilder.append(infos[Debug.MEMINFO_PAGE_TABLES]).append(" kB page tables ");
14161        memInfoBuilder.append(infos[Debug.MEMINFO_KERNEL_STACK]).append(" kB kernel stack\n");
14162        memInfoBuilder.append("           ");
14163        memInfoBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
14164        memInfoBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
14165        memInfoBuilder.append(infos[Debug.MEMINFO_MAPPED]).append(" kB mapped, ");
14166        memInfoBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
14167        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
14168            memInfoBuilder.append("  ZRAM: ");
14169            memInfoBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
14170            memInfoBuilder.append(" kB RAM, ");
14171            memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
14172            memInfoBuilder.append(" kB swap total, ");
14173            memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
14174            memInfoBuilder.append(" kB swap free\n");
14175        }
14176        final long[] ksm = getKsmInfo();
14177        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
14178                || ksm[KSM_VOLATILE] != 0) {
14179            memInfoBuilder.append("  KSM: "); memInfoBuilder.append(ksm[KSM_SHARING]);
14180            memInfoBuilder.append(" kB saved from shared ");
14181            memInfoBuilder.append(ksm[KSM_SHARED]); memInfoBuilder.append(" kB\n");
14182            memInfoBuilder.append("       "); memInfoBuilder.append(ksm[KSM_UNSHARED]);
14183            memInfoBuilder.append(" kB unshared; ");
14184            memInfoBuilder.append(ksm[KSM_VOLATILE]); memInfoBuilder.append(" kB volatile\n");
14185        }
14186        memInfoBuilder.append("  Free RAM: ");
14187        memInfoBuilder.append(cachedPss + memInfo.getCachedSizeKb()
14188                + memInfo.getFreeSizeKb());
14189        memInfoBuilder.append(" kB\n");
14190        memInfoBuilder.append("  Used RAM: ");
14191        memInfoBuilder.append(totalPss - cachedPss + memInfo.getKernelUsedSizeKb());
14192        memInfoBuilder.append(" kB\n");
14193        memInfoBuilder.append("  Lost RAM: ");
14194        memInfoBuilder.append(memInfo.getTotalSizeKb()
14195                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
14196                - memInfo.getKernelUsedSizeKb());
14197        memInfoBuilder.append(" kB\n");
14198        Slog.i(TAG, "Low on memory:");
14199        Slog.i(TAG, shortNativeBuilder.toString());
14200        Slog.i(TAG, fullJavaBuilder.toString());
14201        Slog.i(TAG, memInfoBuilder.toString());
14202
14203        StringBuilder dropBuilder = new StringBuilder(1024);
14204        /*
14205        StringWriter oomSw = new StringWriter();
14206        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
14207        StringWriter catSw = new StringWriter();
14208        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
14209        String[] emptyArgs = new String[] { };
14210        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
14211        oomPw.flush();
14212        String oomString = oomSw.toString();
14213        */
14214        dropBuilder.append("Low on memory:");
14215        dropBuilder.append(stack);
14216        dropBuilder.append('\n');
14217        dropBuilder.append(fullNativeBuilder);
14218        dropBuilder.append(fullJavaBuilder);
14219        dropBuilder.append('\n');
14220        dropBuilder.append(memInfoBuilder);
14221        dropBuilder.append('\n');
14222        /*
14223        dropBuilder.append(oomString);
14224        dropBuilder.append('\n');
14225        */
14226        StringWriter catSw = new StringWriter();
14227        synchronized (ActivityManagerService.this) {
14228            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
14229            String[] emptyArgs = new String[] { };
14230            catPw.println();
14231            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
14232            catPw.println();
14233            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
14234                    false, false, null);
14235            catPw.println();
14236            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
14237            catPw.flush();
14238        }
14239        dropBuilder.append(catSw.toString());
14240        addErrorToDropBox("lowmem", null, "system_server", null,
14241                null, tag.toString(), dropBuilder.toString(), null, null);
14242        //Slog.i(TAG, "Sent to dropbox:");
14243        //Slog.i(TAG, dropBuilder.toString());
14244        synchronized (ActivityManagerService.this) {
14245            long now = SystemClock.uptimeMillis();
14246            if (mLastMemUsageReportTime < now) {
14247                mLastMemUsageReportTime = now;
14248            }
14249        }
14250    }
14251
14252    /**
14253     * Searches array of arguments for the specified string
14254     * @param args array of argument strings
14255     * @param value value to search for
14256     * @return true if the value is contained in the array
14257     */
14258    private static boolean scanArgs(String[] args, String value) {
14259        if (args != null) {
14260            for (String arg : args) {
14261                if (value.equals(arg)) {
14262                    return true;
14263                }
14264            }
14265        }
14266        return false;
14267    }
14268
14269    private final boolean removeDyingProviderLocked(ProcessRecord proc,
14270            ContentProviderRecord cpr, boolean always) {
14271        final boolean inLaunching = mLaunchingProviders.contains(cpr);
14272
14273        if (!inLaunching || always) {
14274            synchronized (cpr) {
14275                cpr.launchingApp = null;
14276                cpr.notifyAll();
14277            }
14278            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
14279            String names[] = cpr.info.authority.split(";");
14280            for (int j = 0; j < names.length; j++) {
14281                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
14282            }
14283        }
14284
14285        for (int i=0; i<cpr.connections.size(); i++) {
14286            ContentProviderConnection conn = cpr.connections.get(i);
14287            if (conn.waiting) {
14288                // If this connection is waiting for the provider, then we don't
14289                // need to mess with its process unless we are always removing
14290                // or for some reason the provider is not currently launching.
14291                if (inLaunching && !always) {
14292                    continue;
14293                }
14294            }
14295            ProcessRecord capp = conn.client;
14296            conn.dead = true;
14297            if (conn.stableCount > 0) {
14298                if (!capp.persistent && capp.thread != null
14299                        && capp.pid != 0
14300                        && capp.pid != MY_PID) {
14301                    capp.kill("depends on provider "
14302                            + cpr.name.flattenToShortString()
14303                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
14304                }
14305            } else if (capp.thread != null && conn.provider.provider != null) {
14306                try {
14307                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
14308                } catch (RemoteException e) {
14309                }
14310                // In the protocol here, we don't expect the client to correctly
14311                // clean up this connection, we'll just remove it.
14312                cpr.connections.remove(i);
14313                if (conn.client.conProviders.remove(conn)) {
14314                    stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
14315                }
14316            }
14317        }
14318
14319        if (inLaunching && always) {
14320            mLaunchingProviders.remove(cpr);
14321        }
14322        return inLaunching;
14323    }
14324
14325    /**
14326     * Main code for cleaning up a process when it has gone away.  This is
14327     * called both as a result of the process dying, or directly when stopping
14328     * a process when running in single process mode.
14329     *
14330     * @return Returns true if the given process has been restarted, so the
14331     * app that was passed in must remain on the process lists.
14332     */
14333    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
14334            boolean restarting, boolean allowRestart, int index) {
14335        if (index >= 0) {
14336            removeLruProcessLocked(app);
14337            ProcessList.remove(app.pid);
14338        }
14339
14340        mProcessesToGc.remove(app);
14341        mPendingPssProcesses.remove(app);
14342
14343        // Dismiss any open dialogs.
14344        if (app.crashDialog != null && !app.forceCrashReport) {
14345            app.crashDialog.dismiss();
14346            app.crashDialog = null;
14347        }
14348        if (app.anrDialog != null) {
14349            app.anrDialog.dismiss();
14350            app.anrDialog = null;
14351        }
14352        if (app.waitDialog != null) {
14353            app.waitDialog.dismiss();
14354            app.waitDialog = null;
14355        }
14356
14357        app.crashing = false;
14358        app.notResponding = false;
14359
14360        app.resetPackageList(mProcessStats);
14361        app.unlinkDeathRecipient();
14362        app.makeInactive(mProcessStats);
14363        app.waitingToKill = null;
14364        app.forcingToForeground = null;
14365        updateProcessForegroundLocked(app, false, false);
14366        app.foregroundActivities = false;
14367        app.hasShownUi = false;
14368        app.treatLikeActivity = false;
14369        app.hasAboveClient = false;
14370        app.hasClientActivities = false;
14371
14372        mServices.killServicesLocked(app, allowRestart);
14373
14374        boolean restart = false;
14375
14376        // Remove published content providers.
14377        for (int i=app.pubProviders.size()-1; i>=0; i--) {
14378            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
14379            final boolean always = app.bad || !allowRestart;
14380            if (removeDyingProviderLocked(app, cpr, always) || always) {
14381                // We left the provider in the launching list, need to
14382                // restart it.
14383                restart = true;
14384            }
14385
14386            cpr.provider = null;
14387            cpr.proc = null;
14388        }
14389        app.pubProviders.clear();
14390
14391        // Take care of any launching providers waiting for this process.
14392        if (checkAppInLaunchingProvidersLocked(app, false)) {
14393            restart = true;
14394        }
14395
14396        // Unregister from connected content providers.
14397        if (!app.conProviders.isEmpty()) {
14398            for (int i=0; i<app.conProviders.size(); i++) {
14399                ContentProviderConnection conn = app.conProviders.get(i);
14400                conn.provider.connections.remove(conn);
14401                stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
14402                        conn.provider.name);
14403            }
14404            app.conProviders.clear();
14405        }
14406
14407        // At this point there may be remaining entries in mLaunchingProviders
14408        // where we were the only one waiting, so they are no longer of use.
14409        // Look for these and clean up if found.
14410        // XXX Commented out for now.  Trying to figure out a way to reproduce
14411        // the actual situation to identify what is actually going on.
14412        if (false) {
14413            for (int i=0; i<mLaunchingProviders.size(); i++) {
14414                ContentProviderRecord cpr = (ContentProviderRecord)
14415                        mLaunchingProviders.get(i);
14416                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
14417                    synchronized (cpr) {
14418                        cpr.launchingApp = null;
14419                        cpr.notifyAll();
14420                    }
14421                }
14422            }
14423        }
14424
14425        skipCurrentReceiverLocked(app);
14426
14427        // Unregister any receivers.
14428        for (int i=app.receivers.size()-1; i>=0; i--) {
14429            removeReceiverLocked(app.receivers.valueAt(i));
14430        }
14431        app.receivers.clear();
14432
14433        // If the app is undergoing backup, tell the backup manager about it
14434        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
14435            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
14436                    + mBackupTarget.appInfo + " died during backup");
14437            try {
14438                IBackupManager bm = IBackupManager.Stub.asInterface(
14439                        ServiceManager.getService(Context.BACKUP_SERVICE));
14440                bm.agentDisconnected(app.info.packageName);
14441            } catch (RemoteException e) {
14442                // can't happen; backup manager is local
14443            }
14444        }
14445
14446        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
14447            ProcessChangeItem item = mPendingProcessChanges.get(i);
14448            if (item.pid == app.pid) {
14449                mPendingProcessChanges.remove(i);
14450                mAvailProcessChanges.add(item);
14451            }
14452        }
14453        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
14454
14455        // If the caller is restarting this app, then leave it in its
14456        // current lists and let the caller take care of it.
14457        if (restarting) {
14458            return false;
14459        }
14460
14461        if (!app.persistent || app.isolated) {
14462            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
14463                    "Removing non-persistent process during cleanup: " + app);
14464            mProcessNames.remove(app.processName, app.uid);
14465            mIsolatedProcesses.remove(app.uid);
14466            if (mHeavyWeightProcess == app) {
14467                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
14468                        mHeavyWeightProcess.userId, 0));
14469                mHeavyWeightProcess = null;
14470            }
14471        } else if (!app.removed) {
14472            // This app is persistent, so we need to keep its record around.
14473            // If it is not already on the pending app list, add it there
14474            // and start a new process for it.
14475            if (mPersistentStartingProcesses.indexOf(app) < 0) {
14476                mPersistentStartingProcesses.add(app);
14477                restart = true;
14478            }
14479        }
14480        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
14481                "Clean-up removing on hold: " + app);
14482        mProcessesOnHold.remove(app);
14483
14484        if (app == mHomeProcess) {
14485            mHomeProcess = null;
14486        }
14487        if (app == mPreviousProcess) {
14488            mPreviousProcess = null;
14489        }
14490
14491        if (restart && !app.isolated) {
14492            // We have components that still need to be running in the
14493            // process, so re-launch it.
14494            if (index < 0) {
14495                ProcessList.remove(app.pid);
14496            }
14497            mProcessNames.put(app.processName, app.uid, app);
14498            startProcessLocked(app, "restart", app.processName);
14499            return true;
14500        } else if (app.pid > 0 && app.pid != MY_PID) {
14501            // Goodbye!
14502            boolean removed;
14503            synchronized (mPidsSelfLocked) {
14504                mPidsSelfLocked.remove(app.pid);
14505                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
14506            }
14507            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
14508            if (app.isolated) {
14509                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
14510            }
14511            app.setPid(0);
14512        }
14513        return false;
14514    }
14515
14516    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
14517        // Look through the content providers we are waiting to have launched,
14518        // and if any run in this process then either schedule a restart of
14519        // the process or kill the client waiting for it if this process has
14520        // gone bad.
14521        int NL = mLaunchingProviders.size();
14522        boolean restart = false;
14523        for (int i=0; i<NL; i++) {
14524            ContentProviderRecord cpr = mLaunchingProviders.get(i);
14525            if (cpr.launchingApp == app) {
14526                if (!alwaysBad && !app.bad) {
14527                    restart = true;
14528                } else {
14529                    removeDyingProviderLocked(app, cpr, true);
14530                    // cpr should have been removed from mLaunchingProviders
14531                    NL = mLaunchingProviders.size();
14532                    i--;
14533                }
14534            }
14535        }
14536        return restart;
14537    }
14538
14539    // =========================================================
14540    // SERVICES
14541    // =========================================================
14542
14543    @Override
14544    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
14545            int flags) {
14546        enforceNotIsolatedCaller("getServices");
14547        synchronized (this) {
14548            return mServices.getRunningServiceInfoLocked(maxNum, flags);
14549        }
14550    }
14551
14552    @Override
14553    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
14554        enforceNotIsolatedCaller("getRunningServiceControlPanel");
14555        synchronized (this) {
14556            return mServices.getRunningServiceControlPanelLocked(name);
14557        }
14558    }
14559
14560    @Override
14561    public ComponentName startService(IApplicationThread caller, Intent service,
14562            String resolvedType, int userId) {
14563        enforceNotIsolatedCaller("startService");
14564        // Refuse possible leaked file descriptors
14565        if (service != null && service.hasFileDescriptors() == true) {
14566            throw new IllegalArgumentException("File descriptors passed in Intent");
14567        }
14568
14569        if (DEBUG_SERVICE)
14570            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
14571        synchronized(this) {
14572            final int callingPid = Binder.getCallingPid();
14573            final int callingUid = Binder.getCallingUid();
14574            final long origId = Binder.clearCallingIdentity();
14575            ComponentName res = mServices.startServiceLocked(caller, service,
14576                    resolvedType, callingPid, callingUid, userId);
14577            Binder.restoreCallingIdentity(origId);
14578            return res;
14579        }
14580    }
14581
14582    ComponentName startServiceInPackage(int uid,
14583            Intent service, String resolvedType, int userId) {
14584        synchronized(this) {
14585            if (DEBUG_SERVICE)
14586                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
14587            final long origId = Binder.clearCallingIdentity();
14588            ComponentName res = mServices.startServiceLocked(null, service,
14589                    resolvedType, -1, uid, userId);
14590            Binder.restoreCallingIdentity(origId);
14591            return res;
14592        }
14593    }
14594
14595    @Override
14596    public int stopService(IApplicationThread caller, Intent service,
14597            String resolvedType, int userId) {
14598        enforceNotIsolatedCaller("stopService");
14599        // Refuse possible leaked file descriptors
14600        if (service != null && service.hasFileDescriptors() == true) {
14601            throw new IllegalArgumentException("File descriptors passed in Intent");
14602        }
14603
14604        synchronized(this) {
14605            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
14606        }
14607    }
14608
14609    @Override
14610    public IBinder peekService(Intent service, String resolvedType) {
14611        enforceNotIsolatedCaller("peekService");
14612        // Refuse possible leaked file descriptors
14613        if (service != null && service.hasFileDescriptors() == true) {
14614            throw new IllegalArgumentException("File descriptors passed in Intent");
14615        }
14616        synchronized(this) {
14617            return mServices.peekServiceLocked(service, resolvedType);
14618        }
14619    }
14620
14621    @Override
14622    public boolean stopServiceToken(ComponentName className, IBinder token,
14623            int startId) {
14624        synchronized(this) {
14625            return mServices.stopServiceTokenLocked(className, token, startId);
14626        }
14627    }
14628
14629    @Override
14630    public void setServiceForeground(ComponentName className, IBinder token,
14631            int id, Notification notification, boolean removeNotification) {
14632        synchronized(this) {
14633            mServices.setServiceForegroundLocked(className, token, id, notification,
14634                    removeNotification);
14635        }
14636    }
14637
14638    @Override
14639    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14640            boolean requireFull, String name, String callerPackage) {
14641        return handleIncomingUser(callingPid, callingUid, userId, allowAll,
14642                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
14643    }
14644
14645    int unsafeConvertIncomingUser(int userId) {
14646        return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
14647                ? mCurrentUserId : userId;
14648    }
14649
14650    int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14651            int allowMode, String name, String callerPackage) {
14652        final int callingUserId = UserHandle.getUserId(callingUid);
14653        if (callingUserId == userId) {
14654            return userId;
14655        }
14656
14657        // Note that we may be accessing mCurrentUserId outside of a lock...
14658        // shouldn't be a big deal, if this is being called outside
14659        // of a locked context there is intrinsically a race with
14660        // the value the caller will receive and someone else changing it.
14661        // We assume that USER_CURRENT_OR_SELF will use the current user; later
14662        // we will switch to the calling user if access to the current user fails.
14663        int targetUserId = unsafeConvertIncomingUser(userId);
14664
14665        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
14666            final boolean allow;
14667            if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
14668                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
14669                // If the caller has this permission, they always pass go.  And collect $200.
14670                allow = true;
14671            } else if (allowMode == ALLOW_FULL_ONLY) {
14672                // We require full access, sucks to be you.
14673                allow = false;
14674            } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
14675                    callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
14676                // If the caller does not have either permission, they are always doomed.
14677                allow = false;
14678            } else if (allowMode == ALLOW_NON_FULL) {
14679                // We are blanket allowing non-full access, you lucky caller!
14680                allow = true;
14681            } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
14682                // We may or may not allow this depending on whether the two users are
14683                // in the same profile.
14684                synchronized (mUserProfileGroupIdsSelfLocked) {
14685                    int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
14686                            UserInfo.NO_PROFILE_GROUP_ID);
14687                    int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
14688                            UserInfo.NO_PROFILE_GROUP_ID);
14689                    allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
14690                            && callingProfile == targetProfile;
14691                }
14692            } else {
14693                throw new IllegalArgumentException("Unknown mode: " + allowMode);
14694            }
14695            if (!allow) {
14696                if (userId == UserHandle.USER_CURRENT_OR_SELF) {
14697                    // In this case, they would like to just execute as their
14698                    // owner user instead of failing.
14699                    targetUserId = callingUserId;
14700                } else {
14701                    StringBuilder builder = new StringBuilder(128);
14702                    builder.append("Permission Denial: ");
14703                    builder.append(name);
14704                    if (callerPackage != null) {
14705                        builder.append(" from ");
14706                        builder.append(callerPackage);
14707                    }
14708                    builder.append(" asks to run as user ");
14709                    builder.append(userId);
14710                    builder.append(" but is calling from user ");
14711                    builder.append(UserHandle.getUserId(callingUid));
14712                    builder.append("; this requires ");
14713                    builder.append(INTERACT_ACROSS_USERS_FULL);
14714                    if (allowMode != ALLOW_FULL_ONLY) {
14715                        builder.append(" or ");
14716                        builder.append(INTERACT_ACROSS_USERS);
14717                    }
14718                    String msg = builder.toString();
14719                    Slog.w(TAG, msg);
14720                    throw new SecurityException(msg);
14721                }
14722            }
14723        }
14724        if (!allowAll && targetUserId < 0) {
14725            throw new IllegalArgumentException(
14726                    "Call does not support special user #" + targetUserId);
14727        }
14728        // Check shell permission
14729        if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) {
14730            if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES,
14731                    targetUserId)) {
14732                throw new SecurityException("Shell does not have permission to access user "
14733                        + targetUserId + "\n " + Debug.getCallers(3));
14734            }
14735        }
14736        return targetUserId;
14737    }
14738
14739    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
14740            String className, int flags) {
14741        boolean result = false;
14742        // For apps that don't have pre-defined UIDs, check for permission
14743        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
14744            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
14745                if (ActivityManager.checkUidPermission(
14746                        INTERACT_ACROSS_USERS,
14747                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
14748                    ComponentName comp = new ComponentName(aInfo.packageName, className);
14749                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
14750                            + " requests FLAG_SINGLE_USER, but app does not hold "
14751                            + INTERACT_ACROSS_USERS;
14752                    Slog.w(TAG, msg);
14753                    throw new SecurityException(msg);
14754                }
14755                // Permission passed
14756                result = true;
14757            }
14758        } else if ("system".equals(componentProcessName)) {
14759            result = true;
14760        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
14761            // Phone app and persistent apps are allowed to export singleuser providers.
14762            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
14763                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
14764        }
14765        if (DEBUG_MU) {
14766            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
14767                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
14768        }
14769        return result;
14770    }
14771
14772    /**
14773     * Checks to see if the caller is in the same app as the singleton
14774     * component, or the component is in a special app. It allows special apps
14775     * to export singleton components but prevents exporting singleton
14776     * components for regular apps.
14777     */
14778    boolean isValidSingletonCall(int callingUid, int componentUid) {
14779        int componentAppId = UserHandle.getAppId(componentUid);
14780        return UserHandle.isSameApp(callingUid, componentUid)
14781                || componentAppId == Process.SYSTEM_UID
14782                || componentAppId == Process.PHONE_UID
14783                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
14784                        == PackageManager.PERMISSION_GRANTED;
14785    }
14786
14787    public int bindService(IApplicationThread caller, IBinder token,
14788            Intent service, String resolvedType,
14789            IServiceConnection connection, int flags, int userId) {
14790        enforceNotIsolatedCaller("bindService");
14791
14792        // Refuse possible leaked file descriptors
14793        if (service != null && service.hasFileDescriptors() == true) {
14794            throw new IllegalArgumentException("File descriptors passed in Intent");
14795        }
14796
14797        synchronized(this) {
14798            return mServices.bindServiceLocked(caller, token, service, resolvedType,
14799                    connection, flags, userId);
14800        }
14801    }
14802
14803    public boolean unbindService(IServiceConnection connection) {
14804        synchronized (this) {
14805            return mServices.unbindServiceLocked(connection);
14806        }
14807    }
14808
14809    public void publishService(IBinder token, Intent intent, IBinder service) {
14810        // Refuse possible leaked file descriptors
14811        if (intent != null && intent.hasFileDescriptors() == true) {
14812            throw new IllegalArgumentException("File descriptors passed in Intent");
14813        }
14814
14815        synchronized(this) {
14816            if (!(token instanceof ServiceRecord)) {
14817                throw new IllegalArgumentException("Invalid service token");
14818            }
14819            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
14820        }
14821    }
14822
14823    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
14824        // Refuse possible leaked file descriptors
14825        if (intent != null && intent.hasFileDescriptors() == true) {
14826            throw new IllegalArgumentException("File descriptors passed in Intent");
14827        }
14828
14829        synchronized(this) {
14830            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
14831        }
14832    }
14833
14834    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
14835        synchronized(this) {
14836            if (!(token instanceof ServiceRecord)) {
14837                Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
14838                throw new IllegalArgumentException("Invalid service token");
14839            }
14840            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
14841        }
14842    }
14843
14844    // =========================================================
14845    // BACKUP AND RESTORE
14846    // =========================================================
14847
14848    // Cause the target app to be launched if necessary and its backup agent
14849    // instantiated.  The backup agent will invoke backupAgentCreated() on the
14850    // activity manager to announce its creation.
14851    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
14852        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
14853        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
14854
14855        synchronized(this) {
14856            // !!! TODO: currently no check here that we're already bound
14857            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
14858            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
14859            synchronized (stats) {
14860                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
14861            }
14862
14863            // Backup agent is now in use, its package can't be stopped.
14864            try {
14865                AppGlobals.getPackageManager().setPackageStoppedState(
14866                        app.packageName, false, UserHandle.getUserId(app.uid));
14867            } catch (RemoteException e) {
14868            } catch (IllegalArgumentException e) {
14869                Slog.w(TAG, "Failed trying to unstop package "
14870                        + app.packageName + ": " + e);
14871            }
14872
14873            BackupRecord r = new BackupRecord(ss, app, backupMode);
14874            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
14875                    ? new ComponentName(app.packageName, app.backupAgentName)
14876                    : new ComponentName("android", "FullBackupAgent");
14877            // startProcessLocked() returns existing proc's record if it's already running
14878            ProcessRecord proc = startProcessLocked(app.processName, app,
14879                    false, 0, "backup", hostingName, false, false, false);
14880            if (proc == null) {
14881                Slog.e(TAG, "Unable to start backup agent process " + r);
14882                return false;
14883            }
14884
14885            r.app = proc;
14886            mBackupTarget = r;
14887            mBackupAppName = app.packageName;
14888
14889            // Try not to kill the process during backup
14890            updateOomAdjLocked(proc);
14891
14892            // If the process is already attached, schedule the creation of the backup agent now.
14893            // If it is not yet live, this will be done when it attaches to the framework.
14894            if (proc.thread != null) {
14895                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
14896                try {
14897                    proc.thread.scheduleCreateBackupAgent(app,
14898                            compatibilityInfoForPackageLocked(app), backupMode);
14899                } catch (RemoteException e) {
14900                    // Will time out on the backup manager side
14901                }
14902            } else {
14903                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
14904            }
14905            // Invariants: at this point, the target app process exists and the application
14906            // is either already running or in the process of coming up.  mBackupTarget and
14907            // mBackupAppName describe the app, so that when it binds back to the AM we
14908            // know that it's scheduled for a backup-agent operation.
14909        }
14910
14911        return true;
14912    }
14913
14914    @Override
14915    public void clearPendingBackup() {
14916        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
14917        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
14918
14919        synchronized (this) {
14920            mBackupTarget = null;
14921            mBackupAppName = null;
14922        }
14923    }
14924
14925    // A backup agent has just come up
14926    public void backupAgentCreated(String agentPackageName, IBinder agent) {
14927        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
14928                + " = " + agent);
14929
14930        synchronized(this) {
14931            if (!agentPackageName.equals(mBackupAppName)) {
14932                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
14933                return;
14934            }
14935        }
14936
14937        long oldIdent = Binder.clearCallingIdentity();
14938        try {
14939            IBackupManager bm = IBackupManager.Stub.asInterface(
14940                    ServiceManager.getService(Context.BACKUP_SERVICE));
14941            bm.agentConnected(agentPackageName, agent);
14942        } catch (RemoteException e) {
14943            // can't happen; the backup manager service is local
14944        } catch (Exception e) {
14945            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
14946            e.printStackTrace();
14947        } finally {
14948            Binder.restoreCallingIdentity(oldIdent);
14949        }
14950    }
14951
14952    // done with this agent
14953    public void unbindBackupAgent(ApplicationInfo appInfo) {
14954        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
14955        if (appInfo == null) {
14956            Slog.w(TAG, "unbind backup agent for null app");
14957            return;
14958        }
14959
14960        synchronized(this) {
14961            try {
14962                if (mBackupAppName == null) {
14963                    Slog.w(TAG, "Unbinding backup agent with no active backup");
14964                    return;
14965                }
14966
14967                if (!mBackupAppName.equals(appInfo.packageName)) {
14968                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
14969                    return;
14970                }
14971
14972                // Not backing this app up any more; reset its OOM adjustment
14973                final ProcessRecord proc = mBackupTarget.app;
14974                updateOomAdjLocked(proc);
14975
14976                // If the app crashed during backup, 'thread' will be null here
14977                if (proc.thread != null) {
14978                    try {
14979                        proc.thread.scheduleDestroyBackupAgent(appInfo,
14980                                compatibilityInfoForPackageLocked(appInfo));
14981                    } catch (Exception e) {
14982                        Slog.e(TAG, "Exception when unbinding backup agent:");
14983                        e.printStackTrace();
14984                    }
14985                }
14986            } finally {
14987                mBackupTarget = null;
14988                mBackupAppName = null;
14989            }
14990        }
14991    }
14992    // =========================================================
14993    // BROADCASTS
14994    // =========================================================
14995
14996    private final List getStickiesLocked(String action, IntentFilter filter,
14997            List cur, int userId) {
14998        final ContentResolver resolver = mContext.getContentResolver();
14999        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15000        if (stickies == null) {
15001            return cur;
15002        }
15003        final ArrayList<Intent> list = stickies.get(action);
15004        if (list == null) {
15005            return cur;
15006        }
15007        int N = list.size();
15008        for (int i=0; i<N; i++) {
15009            Intent intent = list.get(i);
15010            if (filter.match(resolver, intent, true, TAG) >= 0) {
15011                if (cur == null) {
15012                    cur = new ArrayList<Intent>();
15013                }
15014                cur.add(intent);
15015            }
15016        }
15017        return cur;
15018    }
15019
15020    boolean isPendingBroadcastProcessLocked(int pid) {
15021        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
15022                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
15023    }
15024
15025    void skipPendingBroadcastLocked(int pid) {
15026            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
15027            for (BroadcastQueue queue : mBroadcastQueues) {
15028                queue.skipPendingBroadcastLocked(pid);
15029            }
15030    }
15031
15032    // The app just attached; send any pending broadcasts that it should receive
15033    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
15034        boolean didSomething = false;
15035        for (BroadcastQueue queue : mBroadcastQueues) {
15036            didSomething |= queue.sendPendingBroadcastsLocked(app);
15037        }
15038        return didSomething;
15039    }
15040
15041    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
15042            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
15043        enforceNotIsolatedCaller("registerReceiver");
15044        int callingUid;
15045        int callingPid;
15046        synchronized(this) {
15047            ProcessRecord callerApp = null;
15048            if (caller != null) {
15049                callerApp = getRecordForAppLocked(caller);
15050                if (callerApp == null) {
15051                    throw new SecurityException(
15052                            "Unable to find app for caller " + caller
15053                            + " (pid=" + Binder.getCallingPid()
15054                            + ") when registering receiver " + receiver);
15055                }
15056                if (callerApp.info.uid != Process.SYSTEM_UID &&
15057                        !callerApp.pkgList.containsKey(callerPackage) &&
15058                        !"android".equals(callerPackage)) {
15059                    throw new SecurityException("Given caller package " + callerPackage
15060                            + " is not running in process " + callerApp);
15061                }
15062                callingUid = callerApp.info.uid;
15063                callingPid = callerApp.pid;
15064            } else {
15065                callerPackage = null;
15066                callingUid = Binder.getCallingUid();
15067                callingPid = Binder.getCallingPid();
15068            }
15069
15070            userId = this.handleIncomingUser(callingPid, callingUid, userId,
15071                    true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
15072
15073            List allSticky = null;
15074
15075            // Look for any matching sticky broadcasts...
15076            Iterator actions = filter.actionsIterator();
15077            if (actions != null) {
15078                while (actions.hasNext()) {
15079                    String action = (String)actions.next();
15080                    allSticky = getStickiesLocked(action, filter, allSticky,
15081                            UserHandle.USER_ALL);
15082                    allSticky = getStickiesLocked(action, filter, allSticky,
15083                            UserHandle.getUserId(callingUid));
15084                }
15085            } else {
15086                allSticky = getStickiesLocked(null, filter, allSticky,
15087                        UserHandle.USER_ALL);
15088                allSticky = getStickiesLocked(null, filter, allSticky,
15089                        UserHandle.getUserId(callingUid));
15090            }
15091
15092            // The first sticky in the list is returned directly back to
15093            // the client.
15094            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
15095
15096            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
15097                    + ": " + sticky);
15098
15099            if (receiver == null) {
15100                return sticky;
15101            }
15102
15103            ReceiverList rl
15104                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
15105            if (rl == null) {
15106                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
15107                        userId, receiver);
15108                if (rl.app != null) {
15109                    rl.app.receivers.add(rl);
15110                } else {
15111                    try {
15112                        receiver.asBinder().linkToDeath(rl, 0);
15113                    } catch (RemoteException e) {
15114                        return sticky;
15115                    }
15116                    rl.linkedToDeath = true;
15117                }
15118                mRegisteredReceivers.put(receiver.asBinder(), rl);
15119            } else if (rl.uid != callingUid) {
15120                throw new IllegalArgumentException(
15121                        "Receiver requested to register for uid " + callingUid
15122                        + " was previously registered for uid " + rl.uid);
15123            } else if (rl.pid != callingPid) {
15124                throw new IllegalArgumentException(
15125                        "Receiver requested to register for pid " + callingPid
15126                        + " was previously registered for pid " + rl.pid);
15127            } else if (rl.userId != userId) {
15128                throw new IllegalArgumentException(
15129                        "Receiver requested to register for user " + userId
15130                        + " was previously registered for user " + rl.userId);
15131            }
15132            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
15133                    permission, callingUid, userId);
15134            rl.add(bf);
15135            if (!bf.debugCheck()) {
15136                Slog.w(TAG, "==> For Dynamic broadast");
15137            }
15138            mReceiverResolver.addFilter(bf);
15139
15140            // Enqueue broadcasts for all existing stickies that match
15141            // this filter.
15142            if (allSticky != null) {
15143                ArrayList receivers = new ArrayList();
15144                receivers.add(bf);
15145
15146                int N = allSticky.size();
15147                for (int i=0; i<N; i++) {
15148                    Intent intent = (Intent)allSticky.get(i);
15149                    BroadcastQueue queue = broadcastQueueForIntent(intent);
15150                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
15151                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
15152                            null, null, false, true, true, -1);
15153                    queue.enqueueParallelBroadcastLocked(r);
15154                    queue.scheduleBroadcastsLocked();
15155                }
15156            }
15157
15158            return sticky;
15159        }
15160    }
15161
15162    public void unregisterReceiver(IIntentReceiver receiver) {
15163        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
15164
15165        final long origId = Binder.clearCallingIdentity();
15166        try {
15167            boolean doTrim = false;
15168
15169            synchronized(this) {
15170                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
15171                if (rl != null) {
15172                    final BroadcastRecord r = rl.curBroadcast;
15173                    if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
15174                        final boolean doNext = r.queue.finishReceiverLocked(
15175                                r, r.resultCode, r.resultData, r.resultExtras,
15176                                r.resultAbort, false);
15177                        if (doNext) {
15178                            doTrim = true;
15179                            r.queue.processNextBroadcast(false);
15180                        }
15181                    }
15182
15183                    if (rl.app != null) {
15184                        rl.app.receivers.remove(rl);
15185                    }
15186                    removeReceiverLocked(rl);
15187                    if (rl.linkedToDeath) {
15188                        rl.linkedToDeath = false;
15189                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
15190                    }
15191                }
15192            }
15193
15194            // If we actually concluded any broadcasts, we might now be able
15195            // to trim the recipients' apps from our working set
15196            if (doTrim) {
15197                trimApplications();
15198                return;
15199            }
15200
15201        } finally {
15202            Binder.restoreCallingIdentity(origId);
15203        }
15204    }
15205
15206    void removeReceiverLocked(ReceiverList rl) {
15207        mRegisteredReceivers.remove(rl.receiver.asBinder());
15208        int N = rl.size();
15209        for (int i=0; i<N; i++) {
15210            mReceiverResolver.removeFilter(rl.get(i));
15211        }
15212    }
15213
15214    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
15215        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
15216            ProcessRecord r = mLruProcesses.get(i);
15217            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
15218                try {
15219                    r.thread.dispatchPackageBroadcast(cmd, packages);
15220                } catch (RemoteException ex) {
15221                }
15222            }
15223        }
15224    }
15225
15226    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
15227            int callingUid, int[] users) {
15228        List<ResolveInfo> receivers = null;
15229        try {
15230            HashSet<ComponentName> singleUserReceivers = null;
15231            boolean scannedFirstReceivers = false;
15232            for (int user : users) {
15233                // Skip users that have Shell restrictions
15234                if (callingUid == Process.SHELL_UID
15235                        && getUserManagerLocked().hasUserRestriction(
15236                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)) {
15237                    continue;
15238                }
15239                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
15240                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
15241                if (user != 0 && newReceivers != null) {
15242                    // If this is not the primary user, we need to check for
15243                    // any receivers that should be filtered out.
15244                    for (int i=0; i<newReceivers.size(); i++) {
15245                        ResolveInfo ri = newReceivers.get(i);
15246                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
15247                            newReceivers.remove(i);
15248                            i--;
15249                        }
15250                    }
15251                }
15252                if (newReceivers != null && newReceivers.size() == 0) {
15253                    newReceivers = null;
15254                }
15255                if (receivers == null) {
15256                    receivers = newReceivers;
15257                } else if (newReceivers != null) {
15258                    // We need to concatenate the additional receivers
15259                    // found with what we have do far.  This would be easy,
15260                    // but we also need to de-dup any receivers that are
15261                    // singleUser.
15262                    if (!scannedFirstReceivers) {
15263                        // Collect any single user receivers we had already retrieved.
15264                        scannedFirstReceivers = true;
15265                        for (int i=0; i<receivers.size(); i++) {
15266                            ResolveInfo ri = receivers.get(i);
15267                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15268                                ComponentName cn = new ComponentName(
15269                                        ri.activityInfo.packageName, ri.activityInfo.name);
15270                                if (singleUserReceivers == null) {
15271                                    singleUserReceivers = new HashSet<ComponentName>();
15272                                }
15273                                singleUserReceivers.add(cn);
15274                            }
15275                        }
15276                    }
15277                    // Add the new results to the existing results, tracking
15278                    // and de-dupping single user receivers.
15279                    for (int i=0; i<newReceivers.size(); i++) {
15280                        ResolveInfo ri = newReceivers.get(i);
15281                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15282                            ComponentName cn = new ComponentName(
15283                                    ri.activityInfo.packageName, ri.activityInfo.name);
15284                            if (singleUserReceivers == null) {
15285                                singleUserReceivers = new HashSet<ComponentName>();
15286                            }
15287                            if (!singleUserReceivers.contains(cn)) {
15288                                singleUserReceivers.add(cn);
15289                                receivers.add(ri);
15290                            }
15291                        } else {
15292                            receivers.add(ri);
15293                        }
15294                    }
15295                }
15296            }
15297        } catch (RemoteException ex) {
15298            // pm is in same process, this will never happen.
15299        }
15300        return receivers;
15301    }
15302
15303    private final int broadcastIntentLocked(ProcessRecord callerApp,
15304            String callerPackage, Intent intent, String resolvedType,
15305            IIntentReceiver resultTo, int resultCode, String resultData,
15306            Bundle map, String requiredPermission, int appOp,
15307            boolean ordered, boolean sticky, int callingPid, int callingUid,
15308            int userId) {
15309        intent = new Intent(intent);
15310
15311        // By default broadcasts do not go to stopped apps.
15312        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
15313
15314        if (DEBUG_BROADCAST_LIGHT) Slog.v(
15315            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
15316            + " ordered=" + ordered + " userid=" + userId);
15317        if ((resultTo != null) && !ordered) {
15318            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
15319        }
15320
15321        userId = handleIncomingUser(callingPid, callingUid, userId,
15322                true, ALLOW_NON_FULL, "broadcast", callerPackage);
15323
15324        // Make sure that the user who is receiving this broadcast is running.
15325        // If not, we will just skip it. Make an exception for shutdown broadcasts
15326        // and upgrade steps.
15327
15328        if (userId != UserHandle.USER_ALL && !isUserRunningLocked(userId, false)) {
15329            if ((callingUid != Process.SYSTEM_UID
15330                    || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
15331                    && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
15332                Slog.w(TAG, "Skipping broadcast of " + intent
15333                        + ": user " + userId + " is stopped");
15334                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
15335            }
15336        }
15337
15338        /*
15339         * Prevent non-system code (defined here to be non-persistent
15340         * processes) from sending protected broadcasts.
15341         */
15342        int callingAppId = UserHandle.getAppId(callingUid);
15343        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
15344            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
15345            || callingAppId == Process.NFC_UID || callingUid == 0) {
15346            // Always okay.
15347        } else if (callerApp == null || !callerApp.persistent) {
15348            try {
15349                if (AppGlobals.getPackageManager().isProtectedBroadcast(
15350                        intent.getAction())) {
15351                    String msg = "Permission Denial: not allowed to send broadcast "
15352                            + intent.getAction() + " from pid="
15353                            + callingPid + ", uid=" + callingUid;
15354                    Slog.w(TAG, msg);
15355                    throw new SecurityException(msg);
15356                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
15357                    // Special case for compatibility: we don't want apps to send this,
15358                    // but historically it has not been protected and apps may be using it
15359                    // to poke their own app widget.  So, instead of making it protected,
15360                    // just limit it to the caller.
15361                    if (callerApp == null) {
15362                        String msg = "Permission Denial: not allowed to send broadcast "
15363                                + intent.getAction() + " from unknown caller.";
15364                        Slog.w(TAG, msg);
15365                        throw new SecurityException(msg);
15366                    } else if (intent.getComponent() != null) {
15367                        // They are good enough to send to an explicit component...  verify
15368                        // it is being sent to the calling app.
15369                        if (!intent.getComponent().getPackageName().equals(
15370                                callerApp.info.packageName)) {
15371                            String msg = "Permission Denial: not allowed to send broadcast "
15372                                    + intent.getAction() + " to "
15373                                    + intent.getComponent().getPackageName() + " from "
15374                                    + callerApp.info.packageName;
15375                            Slog.w(TAG, msg);
15376                            throw new SecurityException(msg);
15377                        }
15378                    } else {
15379                        // Limit broadcast to their own package.
15380                        intent.setPackage(callerApp.info.packageName);
15381                    }
15382                }
15383            } catch (RemoteException e) {
15384                Slog.w(TAG, "Remote exception", e);
15385                return ActivityManager.BROADCAST_SUCCESS;
15386            }
15387        }
15388
15389        final String action = intent.getAction();
15390        if (action != null) {
15391            switch (action) {
15392                case Intent.ACTION_UID_REMOVED:
15393                case Intent.ACTION_PACKAGE_REMOVED:
15394                case Intent.ACTION_PACKAGE_CHANGED:
15395                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
15396                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
15397                    // Handle special intents: if this broadcast is from the package
15398                    // manager about a package being removed, we need to remove all of
15399                    // its activities from the history stack.
15400                    if (checkComponentPermission(
15401                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
15402                            callingPid, callingUid, -1, true)
15403                            != PackageManager.PERMISSION_GRANTED) {
15404                        String msg = "Permission Denial: " + intent.getAction()
15405                                + " broadcast from " + callerPackage + " (pid=" + callingPid
15406                                + ", uid=" + callingUid + ")"
15407                                + " requires "
15408                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
15409                        Slog.w(TAG, msg);
15410                        throw new SecurityException(msg);
15411                    }
15412                    switch (action) {
15413                        case Intent.ACTION_UID_REMOVED:
15414                            final Bundle intentExtras = intent.getExtras();
15415                            final int uid = intentExtras != null
15416                                    ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
15417                            if (uid >= 0) {
15418                                BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
15419                                synchronized (bs) {
15420                                    bs.removeUidStatsLocked(uid);
15421                                }
15422                                mAppOpsService.uidRemoved(uid);
15423                            }
15424                            break;
15425                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
15426                            // If resources are unavailable just force stop all those packages
15427                            // and flush the attribute cache as well.
15428                            String list[] =
15429                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15430                            if (list != null && list.length > 0) {
15431                                for (int i = 0; i < list.length; i++) {
15432                                    forceStopPackageLocked(list[i], -1, false, true, true,
15433                                            false, false, userId, "storage unmount");
15434                                }
15435                                mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
15436                                sendPackageBroadcastLocked(
15437                                        IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
15438                                        userId);
15439                            }
15440                            break;
15441                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
15442                            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
15443                            break;
15444                        case Intent.ACTION_PACKAGE_REMOVED:
15445                        case Intent.ACTION_PACKAGE_CHANGED:
15446                            Uri data = intent.getData();
15447                            String ssp;
15448                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
15449                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
15450                                boolean fullUninstall = removed &&
15451                                        !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
15452                                if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
15453                                    forceStopPackageLocked(ssp, UserHandle.getAppId(
15454                                            intent.getIntExtra(Intent.EXTRA_UID, -1)),
15455                                            false, true, true, false, fullUninstall, userId,
15456                                            removed ? "pkg removed" : "pkg changed");
15457                                }
15458                                if (removed) {
15459                                    sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
15460                                            new String[] {ssp}, userId);
15461                                    if (fullUninstall) {
15462                                        mAppOpsService.packageRemoved(
15463                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
15464
15465                                        // Remove all permissions granted from/to this package
15466                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
15467
15468                                        removeTasksByPackageNameLocked(ssp, userId);
15469                                        if (userId == UserHandle.USER_OWNER) {
15470                                            mTaskPersister.removeFromPackageCache(ssp);
15471                                        }
15472                                    }
15473                                } else {
15474                                    removeTasksByRemovedPackageComponentsLocked(ssp, userId);
15475                                    if (userId == UserHandle.USER_OWNER) {
15476                                        mTaskPersister.addOtherDeviceTasksToRecentsLocked(ssp);
15477                                    }
15478                                }
15479                            }
15480                            break;
15481                    }
15482                    break;
15483                case Intent.ACTION_PACKAGE_ADDED:
15484                    // Special case for adding a package: by default turn on compatibility mode.
15485                    Uri data = intent.getData();
15486                    String ssp;
15487                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
15488                        final boolean replacing =
15489                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
15490                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
15491
15492                        if (replacing) {
15493                            removeTasksByRemovedPackageComponentsLocked(ssp, userId);
15494                        }
15495                        if (userId == UserHandle.USER_OWNER) {
15496                            mTaskPersister.addOtherDeviceTasksToRecentsLocked(ssp);
15497                        }
15498                    }
15499                    break;
15500                case Intent.ACTION_TIMEZONE_CHANGED:
15501                    // If this is the time zone changed action, queue up a message that will reset
15502                    // the timezone of all currently running processes. This message will get
15503                    // queued up before the broadcast happens.
15504                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
15505                    break;
15506                case Intent.ACTION_TIME_CHANGED:
15507                    // If the user set the time, let all running processes know.
15508                    final int is24Hour =
15509                            intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
15510                                    : 0;
15511                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
15512                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15513                    synchronized (stats) {
15514                        stats.noteCurrentTimeChangedLocked();
15515                    }
15516                    break;
15517                case Intent.ACTION_CLEAR_DNS_CACHE:
15518                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
15519                    break;
15520                case Proxy.PROXY_CHANGE_ACTION:
15521                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
15522                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
15523                    break;
15524            }
15525        }
15526
15527        // Add to the sticky list if requested.
15528        if (sticky) {
15529            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
15530                    callingPid, callingUid)
15531                    != PackageManager.PERMISSION_GRANTED) {
15532                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
15533                        + callingPid + ", uid=" + callingUid
15534                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
15535                Slog.w(TAG, msg);
15536                throw new SecurityException(msg);
15537            }
15538            if (requiredPermission != null) {
15539                Slog.w(TAG, "Can't broadcast sticky intent " + intent
15540                        + " and enforce permission " + requiredPermission);
15541                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
15542            }
15543            if (intent.getComponent() != null) {
15544                throw new SecurityException(
15545                        "Sticky broadcasts can't target a specific component");
15546            }
15547            // We use userId directly here, since the "all" target is maintained
15548            // as a separate set of sticky broadcasts.
15549            if (userId != UserHandle.USER_ALL) {
15550                // But first, if this is not a broadcast to all users, then
15551                // make sure it doesn't conflict with an existing broadcast to
15552                // all users.
15553                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
15554                        UserHandle.USER_ALL);
15555                if (stickies != null) {
15556                    ArrayList<Intent> list = stickies.get(intent.getAction());
15557                    if (list != null) {
15558                        int N = list.size();
15559                        int i;
15560                        for (i=0; i<N; i++) {
15561                            if (intent.filterEquals(list.get(i))) {
15562                                throw new IllegalArgumentException(
15563                                        "Sticky broadcast " + intent + " for user "
15564                                        + userId + " conflicts with existing global broadcast");
15565                            }
15566                        }
15567                    }
15568                }
15569            }
15570            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15571            if (stickies == null) {
15572                stickies = new ArrayMap<String, ArrayList<Intent>>();
15573                mStickyBroadcasts.put(userId, stickies);
15574            }
15575            ArrayList<Intent> list = stickies.get(intent.getAction());
15576            if (list == null) {
15577                list = new ArrayList<Intent>();
15578                stickies.put(intent.getAction(), list);
15579            }
15580            int N = list.size();
15581            int i;
15582            for (i=0; i<N; i++) {
15583                if (intent.filterEquals(list.get(i))) {
15584                    // This sticky already exists, replace it.
15585                    list.set(i, new Intent(intent));
15586                    break;
15587                }
15588            }
15589            if (i >= N) {
15590                list.add(new Intent(intent));
15591            }
15592        }
15593
15594        int[] users;
15595        if (userId == UserHandle.USER_ALL) {
15596            // Caller wants broadcast to go to all started users.
15597            users = mStartedUserArray;
15598        } else {
15599            // Caller wants broadcast to go to one specific user.
15600            users = new int[] {userId};
15601        }
15602
15603        // Figure out who all will receive this broadcast.
15604        List receivers = null;
15605        List<BroadcastFilter> registeredReceivers = null;
15606        // Need to resolve the intent to interested receivers...
15607        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
15608                 == 0) {
15609            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
15610        }
15611        if (intent.getComponent() == null) {
15612            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
15613                // Query one target user at a time, excluding shell-restricted users
15614                UserManagerService ums = getUserManagerLocked();
15615                for (int i = 0; i < users.length; i++) {
15616                    if (ums.hasUserRestriction(
15617                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
15618                        continue;
15619                    }
15620                    List<BroadcastFilter> registeredReceiversForUser =
15621                            mReceiverResolver.queryIntent(intent,
15622                                    resolvedType, false, users[i]);
15623                    if (registeredReceivers == null) {
15624                        registeredReceivers = registeredReceiversForUser;
15625                    } else if (registeredReceiversForUser != null) {
15626                        registeredReceivers.addAll(registeredReceiversForUser);
15627                    }
15628                }
15629            } else {
15630                registeredReceivers = mReceiverResolver.queryIntent(intent,
15631                        resolvedType, false, userId);
15632            }
15633        }
15634
15635        final boolean replacePending =
15636                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
15637
15638        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
15639                + " replacePending=" + replacePending);
15640
15641        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
15642        if (!ordered && NR > 0) {
15643            // If we are not serializing this broadcast, then send the
15644            // registered receivers separately so they don't wait for the
15645            // components to be launched.
15646            final BroadcastQueue queue = broadcastQueueForIntent(intent);
15647            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
15648                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
15649                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
15650                    ordered, sticky, false, userId);
15651            if (DEBUG_BROADCAST) Slog.v(
15652                    TAG, "Enqueueing parallel broadcast " + r);
15653            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
15654            if (!replaced) {
15655                queue.enqueueParallelBroadcastLocked(r);
15656                queue.scheduleBroadcastsLocked();
15657            }
15658            registeredReceivers = null;
15659            NR = 0;
15660        }
15661
15662        // Merge into one list.
15663        int ir = 0;
15664        if (receivers != null) {
15665            // A special case for PACKAGE_ADDED: do not allow the package
15666            // being added to see this broadcast.  This prevents them from
15667            // using this as a back door to get run as soon as they are
15668            // installed.  Maybe in the future we want to have a special install
15669            // broadcast or such for apps, but we'd like to deliberately make
15670            // this decision.
15671            String skipPackages[] = null;
15672            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
15673                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
15674                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
15675                Uri data = intent.getData();
15676                if (data != null) {
15677                    String pkgName = data.getSchemeSpecificPart();
15678                    if (pkgName != null) {
15679                        skipPackages = new String[] { pkgName };
15680                    }
15681                }
15682            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
15683                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15684            }
15685            if (skipPackages != null && (skipPackages.length > 0)) {
15686                for (String skipPackage : skipPackages) {
15687                    if (skipPackage != null) {
15688                        int NT = receivers.size();
15689                        for (int it=0; it<NT; it++) {
15690                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
15691                            if (curt.activityInfo.packageName.equals(skipPackage)) {
15692                                receivers.remove(it);
15693                                it--;
15694                                NT--;
15695                            }
15696                        }
15697                    }
15698                }
15699            }
15700
15701            int NT = receivers != null ? receivers.size() : 0;
15702            int it = 0;
15703            ResolveInfo curt = null;
15704            BroadcastFilter curr = null;
15705            while (it < NT && ir < NR) {
15706                if (curt == null) {
15707                    curt = (ResolveInfo)receivers.get(it);
15708                }
15709                if (curr == null) {
15710                    curr = registeredReceivers.get(ir);
15711                }
15712                if (curr.getPriority() >= curt.priority) {
15713                    // Insert this broadcast record into the final list.
15714                    receivers.add(it, curr);
15715                    ir++;
15716                    curr = null;
15717                    it++;
15718                    NT++;
15719                } else {
15720                    // Skip to the next ResolveInfo in the final list.
15721                    it++;
15722                    curt = null;
15723                }
15724            }
15725        }
15726        while (ir < NR) {
15727            if (receivers == null) {
15728                receivers = new ArrayList();
15729            }
15730            receivers.add(registeredReceivers.get(ir));
15731            ir++;
15732        }
15733
15734        if ((receivers != null && receivers.size() > 0)
15735                || resultTo != null) {
15736            BroadcastQueue queue = broadcastQueueForIntent(intent);
15737            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
15738                    callerPackage, callingPid, callingUid, resolvedType,
15739                    requiredPermission, appOp, receivers, resultTo, resultCode,
15740                    resultData, map, ordered, sticky, false, userId);
15741            if (DEBUG_BROADCAST) Slog.v(
15742                    TAG, "Enqueueing ordered broadcast " + r
15743                    + ": prev had " + queue.mOrderedBroadcasts.size());
15744            if (DEBUG_BROADCAST) {
15745                int seq = r.intent.getIntExtra("seq", -1);
15746                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
15747            }
15748            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
15749            if (!replaced) {
15750                queue.enqueueOrderedBroadcastLocked(r);
15751                queue.scheduleBroadcastsLocked();
15752            }
15753        }
15754
15755        return ActivityManager.BROADCAST_SUCCESS;
15756    }
15757
15758    final Intent verifyBroadcastLocked(Intent intent) {
15759        // Refuse possible leaked file descriptors
15760        if (intent != null && intent.hasFileDescriptors() == true) {
15761            throw new IllegalArgumentException("File descriptors passed in Intent");
15762        }
15763
15764        int flags = intent.getFlags();
15765
15766        if (!mProcessesReady) {
15767            // if the caller really truly claims to know what they're doing, go
15768            // ahead and allow the broadcast without launching any receivers
15769            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
15770                intent = new Intent(intent);
15771                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
15772            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
15773                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
15774                        + " before boot completion");
15775                throw new IllegalStateException("Cannot broadcast before boot completed");
15776            }
15777        }
15778
15779        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
15780            throw new IllegalArgumentException(
15781                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
15782        }
15783
15784        return intent;
15785    }
15786
15787    public final int broadcastIntent(IApplicationThread caller,
15788            Intent intent, String resolvedType, IIntentReceiver resultTo,
15789            int resultCode, String resultData, Bundle map,
15790            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
15791        enforceNotIsolatedCaller("broadcastIntent");
15792        synchronized(this) {
15793            intent = verifyBroadcastLocked(intent);
15794
15795            final ProcessRecord callerApp = getRecordForAppLocked(caller);
15796            final int callingPid = Binder.getCallingPid();
15797            final int callingUid = Binder.getCallingUid();
15798            final long origId = Binder.clearCallingIdentity();
15799            int res = broadcastIntentLocked(callerApp,
15800                    callerApp != null ? callerApp.info.packageName : null,
15801                    intent, resolvedType, resultTo,
15802                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
15803                    callingPid, callingUid, userId);
15804            Binder.restoreCallingIdentity(origId);
15805            return res;
15806        }
15807    }
15808
15809    int broadcastIntentInPackage(String packageName, int uid,
15810            Intent intent, String resolvedType, IIntentReceiver resultTo,
15811            int resultCode, String resultData, Bundle map,
15812            String requiredPermission, boolean serialized, boolean sticky, int userId) {
15813        synchronized(this) {
15814            intent = verifyBroadcastLocked(intent);
15815
15816            final long origId = Binder.clearCallingIdentity();
15817            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
15818                    resultTo, resultCode, resultData, map, requiredPermission,
15819                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
15820            Binder.restoreCallingIdentity(origId);
15821            return res;
15822        }
15823    }
15824
15825    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
15826        // Refuse possible leaked file descriptors
15827        if (intent != null && intent.hasFileDescriptors() == true) {
15828            throw new IllegalArgumentException("File descriptors passed in Intent");
15829        }
15830
15831        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
15832                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
15833
15834        synchronized(this) {
15835            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
15836                    != PackageManager.PERMISSION_GRANTED) {
15837                String msg = "Permission Denial: unbroadcastIntent() from pid="
15838                        + Binder.getCallingPid()
15839                        + ", uid=" + Binder.getCallingUid()
15840                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
15841                Slog.w(TAG, msg);
15842                throw new SecurityException(msg);
15843            }
15844            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15845            if (stickies != null) {
15846                ArrayList<Intent> list = stickies.get(intent.getAction());
15847                if (list != null) {
15848                    int N = list.size();
15849                    int i;
15850                    for (i=0; i<N; i++) {
15851                        if (intent.filterEquals(list.get(i))) {
15852                            list.remove(i);
15853                            break;
15854                        }
15855                    }
15856                    if (list.size() <= 0) {
15857                        stickies.remove(intent.getAction());
15858                    }
15859                }
15860                if (stickies.size() <= 0) {
15861                    mStickyBroadcasts.remove(userId);
15862                }
15863            }
15864        }
15865    }
15866
15867    void backgroundServicesFinishedLocked(int userId) {
15868        for (BroadcastQueue queue : mBroadcastQueues) {
15869            queue.backgroundServicesFinishedLocked(userId);
15870        }
15871    }
15872
15873    public void finishReceiver(IBinder who, int resultCode, String resultData,
15874            Bundle resultExtras, boolean resultAbort, int flags) {
15875        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
15876
15877        // Refuse possible leaked file descriptors
15878        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
15879            throw new IllegalArgumentException("File descriptors passed in Bundle");
15880        }
15881
15882        final long origId = Binder.clearCallingIdentity();
15883        try {
15884            boolean doNext = false;
15885            BroadcastRecord r;
15886
15887            synchronized(this) {
15888                BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
15889                        ? mFgBroadcastQueue : mBgBroadcastQueue;
15890                r = queue.getMatchingOrderedReceiver(who);
15891                if (r != null) {
15892                    doNext = r.queue.finishReceiverLocked(r, resultCode,
15893                        resultData, resultExtras, resultAbort, true);
15894                }
15895            }
15896
15897            if (doNext) {
15898                r.queue.processNextBroadcast(false);
15899            }
15900            trimApplications();
15901        } finally {
15902            Binder.restoreCallingIdentity(origId);
15903        }
15904    }
15905
15906    // =========================================================
15907    // INSTRUMENTATION
15908    // =========================================================
15909
15910    public boolean startInstrumentation(ComponentName className,
15911            String profileFile, int flags, Bundle arguments,
15912            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
15913            int userId, String abiOverride) {
15914        enforceNotIsolatedCaller("startInstrumentation");
15915        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
15916                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
15917        // Refuse possible leaked file descriptors
15918        if (arguments != null && arguments.hasFileDescriptors()) {
15919            throw new IllegalArgumentException("File descriptors passed in Bundle");
15920        }
15921
15922        synchronized(this) {
15923            InstrumentationInfo ii = null;
15924            ApplicationInfo ai = null;
15925            try {
15926                ii = mContext.getPackageManager().getInstrumentationInfo(
15927                    className, STOCK_PM_FLAGS);
15928                ai = AppGlobals.getPackageManager().getApplicationInfo(
15929                        ii.targetPackage, STOCK_PM_FLAGS, userId);
15930            } catch (PackageManager.NameNotFoundException e) {
15931            } catch (RemoteException e) {
15932            }
15933            if (ii == null) {
15934                reportStartInstrumentationFailure(watcher, className,
15935                        "Unable to find instrumentation info for: " + className);
15936                return false;
15937            }
15938            if (ai == null) {
15939                reportStartInstrumentationFailure(watcher, className,
15940                        "Unable to find instrumentation target package: " + ii.targetPackage);
15941                return false;
15942            }
15943
15944            int match = mContext.getPackageManager().checkSignatures(
15945                    ii.targetPackage, ii.packageName);
15946            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
15947                String msg = "Permission Denial: starting instrumentation "
15948                        + className + " from pid="
15949                        + Binder.getCallingPid()
15950                        + ", uid=" + Binder.getCallingPid()
15951                        + " not allowed because package " + ii.packageName
15952                        + " does not have a signature matching the target "
15953                        + ii.targetPackage;
15954                reportStartInstrumentationFailure(watcher, className, msg);
15955                throw new SecurityException(msg);
15956            }
15957
15958            final long origId = Binder.clearCallingIdentity();
15959            // Instrumentation can kill and relaunch even persistent processes
15960            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
15961                    "start instr");
15962            ProcessRecord app = addAppLocked(ai, false, abiOverride);
15963            app.instrumentationClass = className;
15964            app.instrumentationInfo = ai;
15965            app.instrumentationProfileFile = profileFile;
15966            app.instrumentationArguments = arguments;
15967            app.instrumentationWatcher = watcher;
15968            app.instrumentationUiAutomationConnection = uiAutomationConnection;
15969            app.instrumentationResultClass = className;
15970            Binder.restoreCallingIdentity(origId);
15971        }
15972
15973        return true;
15974    }
15975
15976    /**
15977     * Report errors that occur while attempting to start Instrumentation.  Always writes the
15978     * error to the logs, but if somebody is watching, send the report there too.  This enables
15979     * the "am" command to report errors with more information.
15980     *
15981     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
15982     * @param cn The component name of the instrumentation.
15983     * @param report The error report.
15984     */
15985    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
15986            ComponentName cn, String report) {
15987        Slog.w(TAG, report);
15988        try {
15989            if (watcher != null) {
15990                Bundle results = new Bundle();
15991                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
15992                results.putString("Error", report);
15993                watcher.instrumentationStatus(cn, -1, results);
15994            }
15995        } catch (RemoteException e) {
15996            Slog.w(TAG, e);
15997        }
15998    }
15999
16000    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
16001        if (app.instrumentationWatcher != null) {
16002            try {
16003                // NOTE:  IInstrumentationWatcher *must* be oneway here
16004                app.instrumentationWatcher.instrumentationFinished(
16005                    app.instrumentationClass,
16006                    resultCode,
16007                    results);
16008            } catch (RemoteException e) {
16009            }
16010        }
16011        if (app.instrumentationUiAutomationConnection != null) {
16012            try {
16013                app.instrumentationUiAutomationConnection.shutdown();
16014            } catch (RemoteException re) {
16015                /* ignore */
16016            }
16017            // Only a UiAutomation can set this flag and now that
16018            // it is finished we make sure it is reset to its default.
16019            mUserIsMonkey = false;
16020        }
16021        app.instrumentationWatcher = null;
16022        app.instrumentationUiAutomationConnection = null;
16023        app.instrumentationClass = null;
16024        app.instrumentationInfo = null;
16025        app.instrumentationProfileFile = null;
16026        app.instrumentationArguments = null;
16027
16028        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
16029                "finished inst");
16030    }
16031
16032    public void finishInstrumentation(IApplicationThread target,
16033            int resultCode, Bundle results) {
16034        int userId = UserHandle.getCallingUserId();
16035        // Refuse possible leaked file descriptors
16036        if (results != null && results.hasFileDescriptors()) {
16037            throw new IllegalArgumentException("File descriptors passed in Intent");
16038        }
16039
16040        synchronized(this) {
16041            ProcessRecord app = getRecordForAppLocked(target);
16042            if (app == null) {
16043                Slog.w(TAG, "finishInstrumentation: no app for " + target);
16044                return;
16045            }
16046            final long origId = Binder.clearCallingIdentity();
16047            finishInstrumentationLocked(app, resultCode, results);
16048            Binder.restoreCallingIdentity(origId);
16049        }
16050    }
16051
16052    // =========================================================
16053    // CONFIGURATION
16054    // =========================================================
16055
16056    public ConfigurationInfo getDeviceConfigurationInfo() {
16057        ConfigurationInfo config = new ConfigurationInfo();
16058        synchronized (this) {
16059            config.reqTouchScreen = mConfiguration.touchscreen;
16060            config.reqKeyboardType = mConfiguration.keyboard;
16061            config.reqNavigation = mConfiguration.navigation;
16062            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
16063                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
16064                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
16065            }
16066            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
16067                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
16068                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
16069            }
16070            config.reqGlEsVersion = GL_ES_VERSION;
16071        }
16072        return config;
16073    }
16074
16075    ActivityStack getFocusedStack() {
16076        return mStackSupervisor.getFocusedStack();
16077    }
16078
16079    public Configuration getConfiguration() {
16080        Configuration ci;
16081        synchronized(this) {
16082            ci = new Configuration(mConfiguration);
16083            ci.userSetLocale = false;
16084        }
16085        return ci;
16086    }
16087
16088    public void updatePersistentConfiguration(Configuration values) {
16089        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16090                "updateConfiguration()");
16091        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
16092                "updateConfiguration()");
16093        if (values == null) {
16094            throw new NullPointerException("Configuration must not be null");
16095        }
16096
16097        synchronized(this) {
16098            final long origId = Binder.clearCallingIdentity();
16099            updateConfigurationLocked(values, null, true, false);
16100            Binder.restoreCallingIdentity(origId);
16101        }
16102    }
16103
16104    public void updateConfiguration(Configuration values) {
16105        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16106                "updateConfiguration()");
16107
16108        synchronized(this) {
16109            if (values == null && mWindowManager != null) {
16110                // sentinel: fetch the current configuration from the window manager
16111                values = mWindowManager.computeNewConfiguration();
16112            }
16113
16114            if (mWindowManager != null) {
16115                mProcessList.applyDisplaySize(mWindowManager);
16116            }
16117
16118            final long origId = Binder.clearCallingIdentity();
16119            if (values != null) {
16120                Settings.System.clearConfiguration(values);
16121            }
16122            updateConfigurationLocked(values, null, false, false);
16123            Binder.restoreCallingIdentity(origId);
16124        }
16125    }
16126
16127    /**
16128     * Do either or both things: (1) change the current configuration, and (2)
16129     * make sure the given activity is running with the (now) current
16130     * configuration.  Returns true if the activity has been left running, or
16131     * false if <var>starting</var> is being destroyed to match the new
16132     * configuration.
16133     * @param persistent TODO
16134     */
16135    boolean updateConfigurationLocked(Configuration values,
16136            ActivityRecord starting, boolean persistent, boolean initLocale) {
16137        int changes = 0;
16138
16139        if (values != null) {
16140            Configuration newConfig = new Configuration(mConfiguration);
16141            changes = newConfig.updateFrom(values);
16142            if (changes != 0) {
16143                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
16144                    Slog.i(TAG, "Updating configuration to: " + values);
16145                }
16146
16147                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
16148
16149                if (values.locale != null && !initLocale) {
16150                    saveLocaleLocked(values.locale,
16151                                     !values.locale.equals(mConfiguration.locale),
16152                                     values.userSetLocale);
16153                }
16154
16155                mConfigurationSeq++;
16156                if (mConfigurationSeq <= 0) {
16157                    mConfigurationSeq = 1;
16158                }
16159                newConfig.seq = mConfigurationSeq;
16160                mConfiguration = newConfig;
16161                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
16162                mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId);
16163                //mUsageStatsService.noteStartConfig(newConfig);
16164
16165                final Configuration configCopy = new Configuration(mConfiguration);
16166
16167                // TODO: If our config changes, should we auto dismiss any currently
16168                // showing dialogs?
16169                mShowDialogs = shouldShowDialogs(newConfig);
16170
16171                AttributeCache ac = AttributeCache.instance();
16172                if (ac != null) {
16173                    ac.updateConfiguration(configCopy);
16174                }
16175
16176                // Make sure all resources in our process are updated
16177                // right now, so that anyone who is going to retrieve
16178                // resource values after we return will be sure to get
16179                // the new ones.  This is especially important during
16180                // boot, where the first config change needs to guarantee
16181                // all resources have that config before following boot
16182                // code is executed.
16183                mSystemThread.applyConfigurationToResources(configCopy);
16184
16185                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
16186                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
16187                    msg.obj = new Configuration(configCopy);
16188                    mHandler.sendMessage(msg);
16189                }
16190
16191                for (int i=mLruProcesses.size()-1; i>=0; i--) {
16192                    ProcessRecord app = mLruProcesses.get(i);
16193                    try {
16194                        if (app.thread != null) {
16195                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
16196                                    + app.processName + " new config " + mConfiguration);
16197                            app.thread.scheduleConfigurationChanged(configCopy);
16198                        }
16199                    } catch (Exception e) {
16200                    }
16201                }
16202                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
16203                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16204                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
16205                        | Intent.FLAG_RECEIVER_FOREGROUND);
16206                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
16207                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
16208                        Process.SYSTEM_UID, UserHandle.USER_ALL);
16209                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
16210                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
16211                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16212                    broadcastIntentLocked(null, null, intent,
16213                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16214                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16215                }
16216            }
16217        }
16218
16219        boolean kept = true;
16220        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
16221        // mainStack is null during startup.
16222        if (mainStack != null) {
16223            if (changes != 0 && starting == null) {
16224                // If the configuration changed, and the caller is not already
16225                // in the process of starting an activity, then find the top
16226                // activity to check if its configuration needs to change.
16227                starting = mainStack.topRunningActivityLocked(null);
16228            }
16229
16230            if (starting != null) {
16231                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
16232                // And we need to make sure at this point that all other activities
16233                // are made visible with the correct configuration.
16234                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
16235            }
16236        }
16237
16238        if (values != null && mWindowManager != null) {
16239            mWindowManager.setNewConfiguration(mConfiguration);
16240        }
16241
16242        return kept;
16243    }
16244
16245    /**
16246     * Decide based on the configuration whether we should shouw the ANR,
16247     * crash, etc dialogs.  The idea is that if there is no affordnace to
16248     * press the on-screen buttons, we shouldn't show the dialog.
16249     *
16250     * A thought: SystemUI might also want to get told about this, the Power
16251     * dialog / global actions also might want different behaviors.
16252     */
16253    private static final boolean shouldShowDialogs(Configuration config) {
16254        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
16255                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
16256    }
16257
16258    /**
16259     * Save the locale. You must be inside a synchronized (this) block.
16260     */
16261    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
16262        final String languageTag = l.toLanguageTag();
16263        if (isDiff) {
16264            SystemProperties.set("user.locale", languageTag);
16265
16266            // TODO: Who uses these ? There are no references to these system
16267            // properties in documents or code. Did the author intend to call
16268            // System.setProperty() instead ? Even that wouldn't have any effect.
16269            SystemProperties.set("user.language", l.getLanguage());
16270            SystemProperties.set("user.region", l.getCountry());
16271        }
16272
16273        if (isPersist) {
16274            SystemProperties.set("persist.sys.locale", languageTag);
16275
16276            // These values are *deprecated*, use persist.sys.locale instead.
16277            //
16278            // TODO: Stop setting these values once all code that references
16279            // them has been removed.
16280            SystemProperties.set("persist.sys.language", l.getLanguage());
16281            SystemProperties.set("persist.sys.country", l.getCountry());
16282            SystemProperties.set("persist.sys.localevar", l.getVariant());
16283
16284            mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG, l));
16285        }
16286    }
16287
16288    @Override
16289    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
16290        synchronized (this) {
16291            ActivityRecord srec = ActivityRecord.forToken(token);
16292            if (srec.task != null && srec.task.stack != null) {
16293                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
16294            }
16295        }
16296        return false;
16297    }
16298
16299    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
16300            Intent resultData) {
16301
16302        synchronized (this) {
16303            final ActivityStack stack = ActivityRecord.getStackLocked(token);
16304            if (stack != null) {
16305                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
16306            }
16307            return false;
16308        }
16309    }
16310
16311    public int getLaunchedFromUid(IBinder activityToken) {
16312        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16313        if (srec == null) {
16314            return -1;
16315        }
16316        return srec.launchedFromUid;
16317    }
16318
16319    public String getLaunchedFromPackage(IBinder activityToken) {
16320        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16321        if (srec == null) {
16322            return null;
16323        }
16324        return srec.launchedFromPackage;
16325    }
16326
16327    // =========================================================
16328    // LIFETIME MANAGEMENT
16329    // =========================================================
16330
16331    // Returns which broadcast queue the app is the current [or imminent] receiver
16332    // on, or 'null' if the app is not an active broadcast recipient.
16333    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
16334        BroadcastRecord r = app.curReceiver;
16335        if (r != null) {
16336            return r.queue;
16337        }
16338
16339        // It's not the current receiver, but it might be starting up to become one
16340        synchronized (this) {
16341            for (BroadcastQueue queue : mBroadcastQueues) {
16342                r = queue.mPendingBroadcast;
16343                if (r != null && r.curApp == app) {
16344                    // found it; report which queue it's in
16345                    return queue;
16346                }
16347            }
16348        }
16349
16350        return null;
16351    }
16352
16353    Association startAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
16354            ComponentName targetComponent, String targetProcess) {
16355        if (!mTrackingAssociations) {
16356            return null;
16357        }
16358        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
16359                = mAssociations.get(targetUid);
16360        if (components == null) {
16361            components = new ArrayMap<>();
16362            mAssociations.put(targetUid, components);
16363        }
16364        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
16365        if (sourceUids == null) {
16366            sourceUids = new SparseArray<>();
16367            components.put(targetComponent, sourceUids);
16368        }
16369        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
16370        if (sourceProcesses == null) {
16371            sourceProcesses = new ArrayMap<>();
16372            sourceUids.put(sourceUid, sourceProcesses);
16373        }
16374        Association ass = sourceProcesses.get(sourceProcess);
16375        if (ass == null) {
16376            ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
16377                    targetProcess);
16378            sourceProcesses.put(sourceProcess, ass);
16379        }
16380        ass.mCount++;
16381        ass.mNesting++;
16382        if (ass.mNesting == 1) {
16383            ass.mStartTime = SystemClock.uptimeMillis();
16384        }
16385        return ass;
16386    }
16387
16388    void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
16389            ComponentName targetComponent) {
16390        if (!mTrackingAssociations) {
16391            return;
16392        }
16393        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
16394                = mAssociations.get(targetUid);
16395        if (components == null) {
16396            return;
16397        }
16398        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
16399        if (sourceUids == null) {
16400            return;
16401        }
16402        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
16403        if (sourceProcesses == null) {
16404            return;
16405        }
16406        Association ass = sourceProcesses.get(sourceProcess);
16407        if (ass == null || ass.mNesting <= 0) {
16408            return;
16409        }
16410        ass.mNesting--;
16411        if (ass.mNesting == 0) {
16412            ass.mTime += SystemClock.uptimeMillis() - ass.mStartTime;
16413        }
16414    }
16415
16416    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
16417            boolean doingAll, long now) {
16418        if (mAdjSeq == app.adjSeq) {
16419            // This adjustment has already been computed.
16420            return app.curRawAdj;
16421        }
16422
16423        if (app.thread == null) {
16424            app.adjSeq = mAdjSeq;
16425            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16426            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16427            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
16428        }
16429
16430        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
16431        app.adjSource = null;
16432        app.adjTarget = null;
16433        app.empty = false;
16434        app.cached = false;
16435
16436        final int activitiesSize = app.activities.size();
16437
16438        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16439            // The max adjustment doesn't allow this app to be anything
16440            // below foreground, so it is not worth doing work for it.
16441            app.adjType = "fixed";
16442            app.adjSeq = mAdjSeq;
16443            app.curRawAdj = app.maxAdj;
16444            app.foregroundActivities = false;
16445            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
16446            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
16447            // System processes can do UI, and when they do we want to have
16448            // them trim their memory after the user leaves the UI.  To
16449            // facilitate this, here we need to determine whether or not it
16450            // is currently showing UI.
16451            app.systemNoUi = true;
16452            if (app == TOP_APP) {
16453                app.systemNoUi = false;
16454            } else if (activitiesSize > 0) {
16455                for (int j = 0; j < activitiesSize; j++) {
16456                    final ActivityRecord r = app.activities.get(j);
16457                    if (r.visible) {
16458                        app.systemNoUi = false;
16459                    }
16460                }
16461            }
16462            if (!app.systemNoUi) {
16463                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
16464            }
16465            return (app.curAdj=app.maxAdj);
16466        }
16467
16468        app.systemNoUi = false;
16469
16470        // Determine the importance of the process, starting with most
16471        // important to least, and assign an appropriate OOM adjustment.
16472        int adj;
16473        int schedGroup;
16474        int procState;
16475        boolean foregroundActivities = false;
16476        BroadcastQueue queue;
16477        if (app == TOP_APP) {
16478            // The last app on the list is the foreground app.
16479            adj = ProcessList.FOREGROUND_APP_ADJ;
16480            schedGroup = Process.THREAD_GROUP_DEFAULT;
16481            app.adjType = "top-activity";
16482            foregroundActivities = true;
16483            procState = ActivityManager.PROCESS_STATE_TOP;
16484        } else if (app.instrumentationClass != null) {
16485            // Don't want to kill running instrumentation.
16486            adj = ProcessList.FOREGROUND_APP_ADJ;
16487            schedGroup = Process.THREAD_GROUP_DEFAULT;
16488            app.adjType = "instrumentation";
16489            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16490        } else if ((queue = isReceivingBroadcast(app)) != null) {
16491            // An app that is currently receiving a broadcast also
16492            // counts as being in the foreground for OOM killer purposes.
16493            // It's placed in a sched group based on the nature of the
16494            // broadcast as reflected by which queue it's active in.
16495            adj = ProcessList.FOREGROUND_APP_ADJ;
16496            schedGroup = (queue == mFgBroadcastQueue)
16497                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16498            app.adjType = "broadcast";
16499            procState = ActivityManager.PROCESS_STATE_RECEIVER;
16500        } else if (app.executingServices.size() > 0) {
16501            // An app that is currently executing a service callback also
16502            // counts as being in the foreground.
16503            adj = ProcessList.FOREGROUND_APP_ADJ;
16504            schedGroup = app.execServicesFg ?
16505                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16506            app.adjType = "exec-service";
16507            procState = ActivityManager.PROCESS_STATE_SERVICE;
16508            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
16509        } else {
16510            // As far as we know the process is empty.  We may change our mind later.
16511            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16512            // At this point we don't actually know the adjustment.  Use the cached adj
16513            // value that the caller wants us to.
16514            adj = cachedAdj;
16515            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16516            app.cached = true;
16517            app.empty = true;
16518            app.adjType = "cch-empty";
16519        }
16520
16521        // Examine all activities if not already foreground.
16522        if (!foregroundActivities && activitiesSize > 0) {
16523            for (int j = 0; j < activitiesSize; j++) {
16524                final ActivityRecord r = app.activities.get(j);
16525                if (r.app != app) {
16526                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
16527                            + app + "?!?");
16528                    continue;
16529                }
16530                if (r.visible) {
16531                    // App has a visible activity; only upgrade adjustment.
16532                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
16533                        adj = ProcessList.VISIBLE_APP_ADJ;
16534                        app.adjType = "visible";
16535                    }
16536                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16537                        procState = ActivityManager.PROCESS_STATE_TOP;
16538                    }
16539                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16540                    app.cached = false;
16541                    app.empty = false;
16542                    foregroundActivities = true;
16543                    break;
16544                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
16545                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16546                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16547                        app.adjType = "pausing";
16548                    }
16549                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16550                        procState = ActivityManager.PROCESS_STATE_TOP;
16551                    }
16552                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16553                    app.cached = false;
16554                    app.empty = false;
16555                    foregroundActivities = true;
16556                } else if (r.state == ActivityState.STOPPING) {
16557                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16558                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16559                        app.adjType = "stopping";
16560                    }
16561                    // For the process state, we will at this point consider the
16562                    // process to be cached.  It will be cached either as an activity
16563                    // or empty depending on whether the activity is finishing.  We do
16564                    // this so that we can treat the process as cached for purposes of
16565                    // memory trimming (determing current memory level, trim command to
16566                    // send to process) since there can be an arbitrary number of stopping
16567                    // processes and they should soon all go into the cached state.
16568                    if (!r.finishing) {
16569                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
16570                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
16571                        }
16572                    }
16573                    app.cached = false;
16574                    app.empty = false;
16575                    foregroundActivities = true;
16576                } else {
16577                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16578                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
16579                        app.adjType = "cch-act";
16580                    }
16581                }
16582            }
16583        }
16584
16585        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16586            if (app.foregroundServices) {
16587                // The user is aware of this app, so make it visible.
16588                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16589                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16590                app.cached = false;
16591                app.adjType = "fg-service";
16592                schedGroup = Process.THREAD_GROUP_DEFAULT;
16593            } else if (app.forcingToForeground != null) {
16594                // The user is aware of this app, so make it visible.
16595                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16596                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16597                app.cached = false;
16598                app.adjType = "force-fg";
16599                app.adjSource = app.forcingToForeground;
16600                schedGroup = Process.THREAD_GROUP_DEFAULT;
16601            }
16602        }
16603
16604        if (app == mHeavyWeightProcess) {
16605            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
16606                // We don't want to kill the current heavy-weight process.
16607                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
16608                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16609                app.cached = false;
16610                app.adjType = "heavy";
16611            }
16612            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16613                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
16614            }
16615        }
16616
16617        if (app == mHomeProcess) {
16618            if (adj > ProcessList.HOME_APP_ADJ) {
16619                // This process is hosting what we currently consider to be the
16620                // home app, so we don't want to let it go into the background.
16621                adj = ProcessList.HOME_APP_ADJ;
16622                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16623                app.cached = false;
16624                app.adjType = "home";
16625            }
16626            if (procState > ActivityManager.PROCESS_STATE_HOME) {
16627                procState = ActivityManager.PROCESS_STATE_HOME;
16628            }
16629        }
16630
16631        if (app == mPreviousProcess && app.activities.size() > 0) {
16632            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
16633                // This was the previous process that showed UI to the user.
16634                // We want to try to keep it around more aggressively, to give
16635                // a good experience around switching between two apps.
16636                adj = ProcessList.PREVIOUS_APP_ADJ;
16637                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16638                app.cached = false;
16639                app.adjType = "previous";
16640            }
16641            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
16642                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
16643            }
16644        }
16645
16646        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
16647                + " reason=" + app.adjType);
16648
16649        // By default, we use the computed adjustment.  It may be changed if
16650        // there are applications dependent on our services or providers, but
16651        // this gives us a baseline and makes sure we don't get into an
16652        // infinite recursion.
16653        app.adjSeq = mAdjSeq;
16654        app.curRawAdj = adj;
16655        app.hasStartedServices = false;
16656
16657        if (mBackupTarget != null && app == mBackupTarget.app) {
16658            // If possible we want to avoid killing apps while they're being backed up
16659            if (adj > ProcessList.BACKUP_APP_ADJ) {
16660                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
16661                adj = ProcessList.BACKUP_APP_ADJ;
16662                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
16663                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
16664                }
16665                app.adjType = "backup";
16666                app.cached = false;
16667            }
16668            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
16669                procState = ActivityManager.PROCESS_STATE_BACKUP;
16670            }
16671        }
16672
16673        boolean mayBeTop = false;
16674
16675        for (int is = app.services.size()-1;
16676                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16677                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16678                        || procState > ActivityManager.PROCESS_STATE_TOP);
16679                is--) {
16680            ServiceRecord s = app.services.valueAt(is);
16681            if (s.startRequested) {
16682                app.hasStartedServices = true;
16683                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
16684                    procState = ActivityManager.PROCESS_STATE_SERVICE;
16685                }
16686                if (app.hasShownUi && app != mHomeProcess) {
16687                    // If this process has shown some UI, let it immediately
16688                    // go to the LRU list because it may be pretty heavy with
16689                    // UI stuff.  We'll tag it with a label just to help
16690                    // debug and understand what is going on.
16691                    if (adj > ProcessList.SERVICE_ADJ) {
16692                        app.adjType = "cch-started-ui-services";
16693                    }
16694                } else {
16695                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
16696                        // This service has seen some activity within
16697                        // recent memory, so we will keep its process ahead
16698                        // of the background processes.
16699                        if (adj > ProcessList.SERVICE_ADJ) {
16700                            adj = ProcessList.SERVICE_ADJ;
16701                            app.adjType = "started-services";
16702                            app.cached = false;
16703                        }
16704                    }
16705                    // If we have let the service slide into the background
16706                    // state, still have some text describing what it is doing
16707                    // even though the service no longer has an impact.
16708                    if (adj > ProcessList.SERVICE_ADJ) {
16709                        app.adjType = "cch-started-services";
16710                    }
16711                }
16712            }
16713            for (int conni = s.connections.size()-1;
16714                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16715                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16716                            || procState > ActivityManager.PROCESS_STATE_TOP);
16717                    conni--) {
16718                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
16719                for (int i = 0;
16720                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
16721                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16722                                || procState > ActivityManager.PROCESS_STATE_TOP);
16723                        i++) {
16724                    // XXX should compute this based on the max of
16725                    // all connected clients.
16726                    ConnectionRecord cr = clist.get(i);
16727                    if (cr.binding.client == app) {
16728                        // Binding to ourself is not interesting.
16729                        continue;
16730                    }
16731                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
16732                        ProcessRecord client = cr.binding.client;
16733                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
16734                                TOP_APP, doingAll, now);
16735                        int clientProcState = client.curProcState;
16736                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16737                            // If the other app is cached for any reason, for purposes here
16738                            // we are going to consider it empty.  The specific cached state
16739                            // doesn't propagate except under certain conditions.
16740                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16741                        }
16742                        String adjType = null;
16743                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
16744                            // Not doing bind OOM management, so treat
16745                            // this guy more like a started service.
16746                            if (app.hasShownUi && app != mHomeProcess) {
16747                                // If this process has shown some UI, let it immediately
16748                                // go to the LRU list because it may be pretty heavy with
16749                                // UI stuff.  We'll tag it with a label just to help
16750                                // debug and understand what is going on.
16751                                if (adj > clientAdj) {
16752                                    adjType = "cch-bound-ui-services";
16753                                }
16754                                app.cached = false;
16755                                clientAdj = adj;
16756                                clientProcState = procState;
16757                            } else {
16758                                if (now >= (s.lastActivity
16759                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
16760                                    // This service has not seen activity within
16761                                    // recent memory, so allow it to drop to the
16762                                    // LRU list if there is no other reason to keep
16763                                    // it around.  We'll also tag it with a label just
16764                                    // to help debug and undertand what is going on.
16765                                    if (adj > clientAdj) {
16766                                        adjType = "cch-bound-services";
16767                                    }
16768                                    clientAdj = adj;
16769                                }
16770                            }
16771                        }
16772                        if (adj > clientAdj) {
16773                            // If this process has recently shown UI, and
16774                            // the process that is binding to it is less
16775                            // important than being visible, then we don't
16776                            // care about the binding as much as we care
16777                            // about letting this process get into the LRU
16778                            // list to be killed and restarted if needed for
16779                            // memory.
16780                            if (app.hasShownUi && app != mHomeProcess
16781                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16782                                adjType = "cch-bound-ui-services";
16783                            } else {
16784                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
16785                                        |Context.BIND_IMPORTANT)) != 0) {
16786                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
16787                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
16788                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
16789                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
16790                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16791                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16792                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
16793                                    adj = clientAdj;
16794                                } else {
16795                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
16796                                        adj = ProcessList.VISIBLE_APP_ADJ;
16797                                    }
16798                                }
16799                                if (!client.cached) {
16800                                    app.cached = false;
16801                                }
16802                                adjType = "service";
16803                            }
16804                        }
16805                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
16806                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
16807                                schedGroup = Process.THREAD_GROUP_DEFAULT;
16808                            }
16809                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
16810                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
16811                                    // Special handling of clients who are in the top state.
16812                                    // We *may* want to consider this process to be in the
16813                                    // top state as well, but only if there is not another
16814                                    // reason for it to be running.  Being on the top is a
16815                                    // special state, meaning you are specifically running
16816                                    // for the current top app.  If the process is already
16817                                    // running in the background for some other reason, it
16818                                    // is more important to continue considering it to be
16819                                    // in the background state.
16820                                    mayBeTop = true;
16821                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16822                                } else {
16823                                    // Special handling for above-top states (persistent
16824                                    // processes).  These should not bring the current process
16825                                    // into the top state, since they are not on top.  Instead
16826                                    // give them the best state after that.
16827                                    clientProcState =
16828                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16829                                }
16830                            }
16831                        } else {
16832                            if (clientProcState <
16833                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
16834                                clientProcState =
16835                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
16836                            }
16837                        }
16838                        if (procState > clientProcState) {
16839                            procState = clientProcState;
16840                        }
16841                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16842                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
16843                            app.pendingUiClean = true;
16844                        }
16845                        if (adjType != null) {
16846                            app.adjType = adjType;
16847                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16848                                    .REASON_SERVICE_IN_USE;
16849                            app.adjSource = cr.binding.client;
16850                            app.adjSourceProcState = clientProcState;
16851                            app.adjTarget = s.name;
16852                        }
16853                    }
16854                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
16855                        app.treatLikeActivity = true;
16856                    }
16857                    final ActivityRecord a = cr.activity;
16858                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
16859                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
16860                                (a.visible || a.state == ActivityState.RESUMED
16861                                 || a.state == ActivityState.PAUSING)) {
16862                            adj = ProcessList.FOREGROUND_APP_ADJ;
16863                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
16864                                schedGroup = Process.THREAD_GROUP_DEFAULT;
16865                            }
16866                            app.cached = false;
16867                            app.adjType = "service";
16868                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16869                                    .REASON_SERVICE_IN_USE;
16870                            app.adjSource = a;
16871                            app.adjSourceProcState = procState;
16872                            app.adjTarget = s.name;
16873                        }
16874                    }
16875                }
16876            }
16877        }
16878
16879        for (int provi = app.pubProviders.size()-1;
16880                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16881                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16882                        || procState > ActivityManager.PROCESS_STATE_TOP);
16883                provi--) {
16884            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
16885            for (int i = cpr.connections.size()-1;
16886                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16887                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16888                            || procState > ActivityManager.PROCESS_STATE_TOP);
16889                    i--) {
16890                ContentProviderConnection conn = cpr.connections.get(i);
16891                ProcessRecord client = conn.client;
16892                if (client == app) {
16893                    // Being our own client is not interesting.
16894                    continue;
16895                }
16896                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
16897                int clientProcState = client.curProcState;
16898                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16899                    // If the other app is cached for any reason, for purposes here
16900                    // we are going to consider it empty.
16901                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16902                }
16903                if (adj > clientAdj) {
16904                    if (app.hasShownUi && app != mHomeProcess
16905                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16906                        app.adjType = "cch-ui-provider";
16907                    } else {
16908                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
16909                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
16910                        app.adjType = "provider";
16911                    }
16912                    app.cached &= client.cached;
16913                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16914                            .REASON_PROVIDER_IN_USE;
16915                    app.adjSource = client;
16916                    app.adjSourceProcState = clientProcState;
16917                    app.adjTarget = cpr.name;
16918                }
16919                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
16920                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
16921                        // Special handling of clients who are in the top state.
16922                        // We *may* want to consider this process to be in the
16923                        // top state as well, but only if there is not another
16924                        // reason for it to be running.  Being on the top is a
16925                        // special state, meaning you are specifically running
16926                        // for the current top app.  If the process is already
16927                        // running in the background for some other reason, it
16928                        // is more important to continue considering it to be
16929                        // in the background state.
16930                        mayBeTop = true;
16931                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16932                    } else {
16933                        // Special handling for above-top states (persistent
16934                        // processes).  These should not bring the current process
16935                        // into the top state, since they are not on top.  Instead
16936                        // give them the best state after that.
16937                        clientProcState =
16938                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16939                    }
16940                }
16941                if (procState > clientProcState) {
16942                    procState = clientProcState;
16943                }
16944                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
16945                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16946                }
16947            }
16948            // If the provider has external (non-framework) process
16949            // dependencies, ensure that its adjustment is at least
16950            // FOREGROUND_APP_ADJ.
16951            if (cpr.hasExternalProcessHandles()) {
16952                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
16953                    adj = ProcessList.FOREGROUND_APP_ADJ;
16954                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16955                    app.cached = false;
16956                    app.adjType = "provider";
16957                    app.adjTarget = cpr.name;
16958                }
16959                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
16960                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16961                }
16962            }
16963        }
16964
16965        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
16966            // A client of one of our services or providers is in the top state.  We
16967            // *may* want to be in the top state, but not if we are already running in
16968            // the background for some other reason.  For the decision here, we are going
16969            // to pick out a few specific states that we want to remain in when a client
16970            // is top (states that tend to be longer-term) and otherwise allow it to go
16971            // to the top state.
16972            switch (procState) {
16973                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
16974                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
16975                case ActivityManager.PROCESS_STATE_SERVICE:
16976                    // These all are longer-term states, so pull them up to the top
16977                    // of the background states, but not all the way to the top state.
16978                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16979                    break;
16980                default:
16981                    // Otherwise, top is a better choice, so take it.
16982                    procState = ActivityManager.PROCESS_STATE_TOP;
16983                    break;
16984            }
16985        }
16986
16987        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
16988            if (app.hasClientActivities) {
16989                // This is a cached process, but with client activities.  Mark it so.
16990                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
16991                app.adjType = "cch-client-act";
16992            } else if (app.treatLikeActivity) {
16993                // This is a cached process, but somebody wants us to treat it like it has
16994                // an activity, okay!
16995                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
16996                app.adjType = "cch-as-act";
16997            }
16998        }
16999
17000        if (adj == ProcessList.SERVICE_ADJ) {
17001            if (doingAll) {
17002                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
17003                mNewNumServiceProcs++;
17004                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
17005                if (!app.serviceb) {
17006                    // This service isn't far enough down on the LRU list to
17007                    // normally be a B service, but if we are low on RAM and it
17008                    // is large we want to force it down since we would prefer to
17009                    // keep launcher over it.
17010                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
17011                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
17012                        app.serviceHighRam = true;
17013                        app.serviceb = true;
17014                        //Slog.i(TAG, "ADJ " + app + " high ram!");
17015                    } else {
17016                        mNewNumAServiceProcs++;
17017                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
17018                    }
17019                } else {
17020                    app.serviceHighRam = false;
17021                }
17022            }
17023            if (app.serviceb) {
17024                adj = ProcessList.SERVICE_B_ADJ;
17025            }
17026        }
17027
17028        app.curRawAdj = adj;
17029
17030        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
17031        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
17032        if (adj > app.maxAdj) {
17033            adj = app.maxAdj;
17034            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
17035                schedGroup = Process.THREAD_GROUP_DEFAULT;
17036            }
17037        }
17038
17039        // Do final modification to adj.  Everything we do between here and applying
17040        // the final setAdj must be done in this function, because we will also use
17041        // it when computing the final cached adj later.  Note that we don't need to
17042        // worry about this for max adj above, since max adj will always be used to
17043        // keep it out of the cached vaues.
17044        app.curAdj = app.modifyRawOomAdj(adj);
17045        app.curSchedGroup = schedGroup;
17046        app.curProcState = procState;
17047        app.foregroundActivities = foregroundActivities;
17048
17049        return app.curRawAdj;
17050    }
17051
17052    /**
17053     * Record new PSS sample for a process.
17054     */
17055    void recordPssSample(ProcessRecord proc, int procState, long pss, long uss, long now) {
17056        proc.lastPssTime = now;
17057        proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
17058        if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
17059                + ": " + pss + " lastPss=" + proc.lastPss
17060                + " state=" + ProcessList.makeProcStateString(procState));
17061        if (proc.initialIdlePss == 0) {
17062            proc.initialIdlePss = pss;
17063        }
17064        proc.lastPss = pss;
17065        if (procState >= ActivityManager.PROCESS_STATE_HOME) {
17066            proc.lastCachedPss = pss;
17067        }
17068    }
17069
17070    /**
17071     * Schedule PSS collection of a process.
17072     */
17073    void requestPssLocked(ProcessRecord proc, int procState) {
17074        if (mPendingPssProcesses.contains(proc)) {
17075            return;
17076        }
17077        if (mPendingPssProcesses.size() == 0) {
17078            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
17079        }
17080        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
17081        proc.pssProcState = procState;
17082        mPendingPssProcesses.add(proc);
17083    }
17084
17085    /**
17086     * Schedule PSS collection of all processes.
17087     */
17088    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
17089        if (!always) {
17090            if (now < (mLastFullPssTime +
17091                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
17092                return;
17093            }
17094        }
17095        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
17096        mLastFullPssTime = now;
17097        mFullPssPending = true;
17098        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
17099        mPendingPssProcesses.clear();
17100        for (int i=mLruProcesses.size()-1; i>=0; i--) {
17101            ProcessRecord app = mLruProcesses.get(i);
17102            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
17103                app.pssProcState = app.setProcState;
17104                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17105                        mTestPssMode, isSleeping(), now);
17106                mPendingPssProcesses.add(app);
17107            }
17108        }
17109        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
17110    }
17111
17112    public void setTestPssMode(boolean enabled) {
17113        synchronized (this) {
17114            mTestPssMode = enabled;
17115            if (enabled) {
17116                // Whenever we enable the mode, we want to take a snapshot all of current
17117                // process mem use.
17118                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
17119            }
17120        }
17121    }
17122
17123    /**
17124     * Ask a given process to GC right now.
17125     */
17126    final void performAppGcLocked(ProcessRecord app) {
17127        try {
17128            app.lastRequestedGc = SystemClock.uptimeMillis();
17129            if (app.thread != null) {
17130                if (app.reportLowMemory) {
17131                    app.reportLowMemory = false;
17132                    app.thread.scheduleLowMemory();
17133                } else {
17134                    app.thread.processInBackground();
17135                }
17136            }
17137        } catch (Exception e) {
17138            // whatever.
17139        }
17140    }
17141
17142    /**
17143     * Returns true if things are idle enough to perform GCs.
17144     */
17145    private final boolean canGcNowLocked() {
17146        boolean processingBroadcasts = false;
17147        for (BroadcastQueue q : mBroadcastQueues) {
17148            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
17149                processingBroadcasts = true;
17150            }
17151        }
17152        return !processingBroadcasts
17153                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
17154    }
17155
17156    /**
17157     * Perform GCs on all processes that are waiting for it, but only
17158     * if things are idle.
17159     */
17160    final void performAppGcsLocked() {
17161        final int N = mProcessesToGc.size();
17162        if (N <= 0) {
17163            return;
17164        }
17165        if (canGcNowLocked()) {
17166            while (mProcessesToGc.size() > 0) {
17167                ProcessRecord proc = mProcessesToGc.remove(0);
17168                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
17169                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
17170                            <= SystemClock.uptimeMillis()) {
17171                        // To avoid spamming the system, we will GC processes one
17172                        // at a time, waiting a few seconds between each.
17173                        performAppGcLocked(proc);
17174                        scheduleAppGcsLocked();
17175                        return;
17176                    } else {
17177                        // It hasn't been long enough since we last GCed this
17178                        // process...  put it in the list to wait for its time.
17179                        addProcessToGcListLocked(proc);
17180                        break;
17181                    }
17182                }
17183            }
17184
17185            scheduleAppGcsLocked();
17186        }
17187    }
17188
17189    /**
17190     * If all looks good, perform GCs on all processes waiting for them.
17191     */
17192    final void performAppGcsIfAppropriateLocked() {
17193        if (canGcNowLocked()) {
17194            performAppGcsLocked();
17195            return;
17196        }
17197        // Still not idle, wait some more.
17198        scheduleAppGcsLocked();
17199    }
17200
17201    /**
17202     * Schedule the execution of all pending app GCs.
17203     */
17204    final void scheduleAppGcsLocked() {
17205        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
17206
17207        if (mProcessesToGc.size() > 0) {
17208            // Schedule a GC for the time to the next process.
17209            ProcessRecord proc = mProcessesToGc.get(0);
17210            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
17211
17212            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
17213            long now = SystemClock.uptimeMillis();
17214            if (when < (now+GC_TIMEOUT)) {
17215                when = now + GC_TIMEOUT;
17216            }
17217            mHandler.sendMessageAtTime(msg, when);
17218        }
17219    }
17220
17221    /**
17222     * Add a process to the array of processes waiting to be GCed.  Keeps the
17223     * list in sorted order by the last GC time.  The process can't already be
17224     * on the list.
17225     */
17226    final void addProcessToGcListLocked(ProcessRecord proc) {
17227        boolean added = false;
17228        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
17229            if (mProcessesToGc.get(i).lastRequestedGc <
17230                    proc.lastRequestedGc) {
17231                added = true;
17232                mProcessesToGc.add(i+1, proc);
17233                break;
17234            }
17235        }
17236        if (!added) {
17237            mProcessesToGc.add(0, proc);
17238        }
17239    }
17240
17241    /**
17242     * Set up to ask a process to GC itself.  This will either do it
17243     * immediately, or put it on the list of processes to gc the next
17244     * time things are idle.
17245     */
17246    final void scheduleAppGcLocked(ProcessRecord app) {
17247        long now = SystemClock.uptimeMillis();
17248        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
17249            return;
17250        }
17251        if (!mProcessesToGc.contains(app)) {
17252            addProcessToGcListLocked(app);
17253            scheduleAppGcsLocked();
17254        }
17255    }
17256
17257    final void checkExcessivePowerUsageLocked(boolean doKills) {
17258        updateCpuStatsNow();
17259
17260        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17261        boolean doWakeKills = doKills;
17262        boolean doCpuKills = doKills;
17263        if (mLastPowerCheckRealtime == 0) {
17264            doWakeKills = false;
17265        }
17266        if (mLastPowerCheckUptime == 0) {
17267            doCpuKills = false;
17268        }
17269        if (stats.isScreenOn()) {
17270            doWakeKills = false;
17271        }
17272        final long curRealtime = SystemClock.elapsedRealtime();
17273        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
17274        final long curUptime = SystemClock.uptimeMillis();
17275        final long uptimeSince = curUptime - mLastPowerCheckUptime;
17276        mLastPowerCheckRealtime = curRealtime;
17277        mLastPowerCheckUptime = curUptime;
17278        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
17279            doWakeKills = false;
17280        }
17281        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
17282            doCpuKills = false;
17283        }
17284        int i = mLruProcesses.size();
17285        while (i > 0) {
17286            i--;
17287            ProcessRecord app = mLruProcesses.get(i);
17288            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17289                long wtime;
17290                synchronized (stats) {
17291                    wtime = stats.getProcessWakeTime(app.info.uid,
17292                            app.pid, curRealtime);
17293                }
17294                long wtimeUsed = wtime - app.lastWakeTime;
17295                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
17296                if (DEBUG_POWER) {
17297                    StringBuilder sb = new StringBuilder(128);
17298                    sb.append("Wake for ");
17299                    app.toShortString(sb);
17300                    sb.append(": over ");
17301                    TimeUtils.formatDuration(realtimeSince, sb);
17302                    sb.append(" used ");
17303                    TimeUtils.formatDuration(wtimeUsed, sb);
17304                    sb.append(" (");
17305                    sb.append((wtimeUsed*100)/realtimeSince);
17306                    sb.append("%)");
17307                    Slog.i(TAG, sb.toString());
17308                    sb.setLength(0);
17309                    sb.append("CPU for ");
17310                    app.toShortString(sb);
17311                    sb.append(": over ");
17312                    TimeUtils.formatDuration(uptimeSince, sb);
17313                    sb.append(" used ");
17314                    TimeUtils.formatDuration(cputimeUsed, sb);
17315                    sb.append(" (");
17316                    sb.append((cputimeUsed*100)/uptimeSince);
17317                    sb.append("%)");
17318                    Slog.i(TAG, sb.toString());
17319                }
17320                // If a process has held a wake lock for more
17321                // than 50% of the time during this period,
17322                // that sounds bad.  Kill!
17323                if (doWakeKills && realtimeSince > 0
17324                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
17325                    synchronized (stats) {
17326                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
17327                                realtimeSince, wtimeUsed);
17328                    }
17329                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
17330                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
17331                } else if (doCpuKills && uptimeSince > 0
17332                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
17333                    synchronized (stats) {
17334                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
17335                                uptimeSince, cputimeUsed);
17336                    }
17337                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
17338                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
17339                } else {
17340                    app.lastWakeTime = wtime;
17341                    app.lastCpuTime = app.curCpuTime;
17342                }
17343            }
17344        }
17345    }
17346
17347    private final boolean applyOomAdjLocked(ProcessRecord app,
17348            ProcessRecord TOP_APP, boolean doingAll, long now) {
17349        boolean success = true;
17350
17351        if (app.curRawAdj != app.setRawAdj) {
17352            app.setRawAdj = app.curRawAdj;
17353        }
17354
17355        int changes = 0;
17356
17357        if (app.curAdj != app.setAdj) {
17358            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
17359            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
17360                TAG, "Set " + app.pid + " " + app.processName +
17361                " adj " + app.curAdj + ": " + app.adjType);
17362            app.setAdj = app.curAdj;
17363        }
17364
17365        if (app.setSchedGroup != app.curSchedGroup) {
17366            app.setSchedGroup = app.curSchedGroup;
17367            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17368                    "Setting process group of " + app.processName
17369                    + " to " + app.curSchedGroup);
17370            if (app.waitingToKill != null &&
17371                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
17372                app.kill(app.waitingToKill, true);
17373                success = false;
17374            } else {
17375                if (true) {
17376                    long oldId = Binder.clearCallingIdentity();
17377                    try {
17378                        Process.setProcessGroup(app.pid, app.curSchedGroup);
17379                    } catch (Exception e) {
17380                        Slog.w(TAG, "Failed setting process group of " + app.pid
17381                                + " to " + app.curSchedGroup);
17382                        e.printStackTrace();
17383                    } finally {
17384                        Binder.restoreCallingIdentity(oldId);
17385                    }
17386                } else {
17387                    if (app.thread != null) {
17388                        try {
17389                            app.thread.setSchedulingGroup(app.curSchedGroup);
17390                        } catch (RemoteException e) {
17391                        }
17392                    }
17393                }
17394                Process.setSwappiness(app.pid,
17395                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
17396            }
17397        }
17398        if (app.repForegroundActivities != app.foregroundActivities) {
17399            app.repForegroundActivities = app.foregroundActivities;
17400            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
17401        }
17402        if (app.repProcState != app.curProcState) {
17403            app.repProcState = app.curProcState;
17404            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
17405            if (app.thread != null) {
17406                try {
17407                    if (false) {
17408                        //RuntimeException h = new RuntimeException("here");
17409                        Slog.i(TAG, "Sending new process state " + app.repProcState
17410                                + " to " + app /*, h*/);
17411                    }
17412                    app.thread.setProcessState(app.repProcState);
17413                } catch (RemoteException e) {
17414                }
17415            }
17416        }
17417        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
17418                app.setProcState)) {
17419            if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
17420                // Experimental code to more aggressively collect pss while
17421                // running test...  the problem is that this tends to collect
17422                // the data right when a process is transitioning between process
17423                // states, which well tend to give noisy data.
17424                long start = SystemClock.uptimeMillis();
17425                long pss = Debug.getPss(app.pid, mTmpLong, null);
17426                recordPssSample(app, app.curProcState, pss, mTmpLong[0], now);
17427                mPendingPssProcesses.remove(app);
17428                Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
17429                        + " to " + app.curProcState + ": "
17430                        + (SystemClock.uptimeMillis()-start) + "ms");
17431            }
17432            app.lastStateTime = now;
17433            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17434                    mTestPssMode, isSleeping(), now);
17435            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
17436                    + ProcessList.makeProcStateString(app.setProcState) + " to "
17437                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
17438                    + (app.nextPssTime-now) + ": " + app);
17439        } else {
17440            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
17441                    && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
17442                    mTestPssMode)))) {
17443                requestPssLocked(app, app.setProcState);
17444                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
17445                        mTestPssMode, isSleeping(), now);
17446            } else if (false && DEBUG_PSS) {
17447                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
17448            }
17449        }
17450        if (app.setProcState != app.curProcState) {
17451            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17452                    "Proc state change of " + app.processName
17453                    + " to " + app.curProcState);
17454            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
17455            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
17456            if (setImportant && !curImportant) {
17457                // This app is no longer something we consider important enough to allow to
17458                // use arbitrary amounts of battery power.  Note
17459                // its current wake lock time to later know to kill it if
17460                // it is not behaving well.
17461                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17462                synchronized (stats) {
17463                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
17464                            app.pid, SystemClock.elapsedRealtime());
17465                }
17466                app.lastCpuTime = app.curCpuTime;
17467
17468            }
17469            app.setProcState = app.curProcState;
17470            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17471                app.notCachedSinceIdle = false;
17472            }
17473            if (!doingAll) {
17474                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
17475            } else {
17476                app.procStateChanged = true;
17477            }
17478        }
17479
17480        if (changes != 0) {
17481            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
17482            int i = mPendingProcessChanges.size()-1;
17483            ProcessChangeItem item = null;
17484            while (i >= 0) {
17485                item = mPendingProcessChanges.get(i);
17486                if (item.pid == app.pid) {
17487                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
17488                    break;
17489                }
17490                i--;
17491            }
17492            if (i < 0) {
17493                // No existing item in pending changes; need a new one.
17494                final int NA = mAvailProcessChanges.size();
17495                if (NA > 0) {
17496                    item = mAvailProcessChanges.remove(NA-1);
17497                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
17498                } else {
17499                    item = new ProcessChangeItem();
17500                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
17501                }
17502                item.changes = 0;
17503                item.pid = app.pid;
17504                item.uid = app.info.uid;
17505                if (mPendingProcessChanges.size() == 0) {
17506                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
17507                            "*** Enqueueing dispatch processes changed!");
17508                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
17509                }
17510                mPendingProcessChanges.add(item);
17511            }
17512            item.changes |= changes;
17513            item.processState = app.repProcState;
17514            item.foregroundActivities = app.repForegroundActivities;
17515            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
17516                    + Integer.toHexString(System.identityHashCode(item))
17517                    + " " + app.toShortString() + ": changes=" + item.changes
17518                    + " procState=" + item.processState
17519                    + " foreground=" + item.foregroundActivities
17520                    + " type=" + app.adjType + " source=" + app.adjSource
17521                    + " target=" + app.adjTarget);
17522        }
17523
17524        return success;
17525    }
17526
17527    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
17528        if (proc.thread != null) {
17529            if (proc.baseProcessTracker != null) {
17530                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
17531            }
17532            if (proc.repProcState >= 0) {
17533                mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
17534                        proc.repProcState);
17535            }
17536        }
17537    }
17538
17539    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
17540            ProcessRecord TOP_APP, boolean doingAll, long now) {
17541        if (app.thread == null) {
17542            return false;
17543        }
17544
17545        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
17546
17547        return applyOomAdjLocked(app, TOP_APP, doingAll, now);
17548    }
17549
17550    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
17551            boolean oomAdj) {
17552        if (isForeground != proc.foregroundServices) {
17553            proc.foregroundServices = isForeground;
17554            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
17555                    proc.info.uid);
17556            if (isForeground) {
17557                if (curProcs == null) {
17558                    curProcs = new ArrayList<ProcessRecord>();
17559                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
17560                }
17561                if (!curProcs.contains(proc)) {
17562                    curProcs.add(proc);
17563                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
17564                            proc.info.packageName, proc.info.uid);
17565                }
17566            } else {
17567                if (curProcs != null) {
17568                    if (curProcs.remove(proc)) {
17569                        mBatteryStatsService.noteEvent(
17570                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
17571                                proc.info.packageName, proc.info.uid);
17572                        if (curProcs.size() <= 0) {
17573                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
17574                        }
17575                    }
17576                }
17577            }
17578            if (oomAdj) {
17579                updateOomAdjLocked();
17580            }
17581        }
17582    }
17583
17584    private final ActivityRecord resumedAppLocked() {
17585        ActivityRecord act = mStackSupervisor.resumedAppLocked();
17586        String pkg;
17587        int uid;
17588        if (act != null) {
17589            pkg = act.packageName;
17590            uid = act.info.applicationInfo.uid;
17591        } else {
17592            pkg = null;
17593            uid = -1;
17594        }
17595        // Has the UID or resumed package name changed?
17596        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
17597                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
17598            if (mCurResumedPackage != null) {
17599                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
17600                        mCurResumedPackage, mCurResumedUid);
17601            }
17602            mCurResumedPackage = pkg;
17603            mCurResumedUid = uid;
17604            if (mCurResumedPackage != null) {
17605                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
17606                        mCurResumedPackage, mCurResumedUid);
17607            }
17608        }
17609        return act;
17610    }
17611
17612    final boolean updateOomAdjLocked(ProcessRecord app) {
17613        final ActivityRecord TOP_ACT = resumedAppLocked();
17614        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17615        final boolean wasCached = app.cached;
17616
17617        mAdjSeq++;
17618
17619        // This is the desired cached adjusment we want to tell it to use.
17620        // If our app is currently cached, we know it, and that is it.  Otherwise,
17621        // we don't know it yet, and it needs to now be cached we will then
17622        // need to do a complete oom adj.
17623        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
17624                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
17625        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
17626                SystemClock.uptimeMillis());
17627        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
17628            // Changed to/from cached state, so apps after it in the LRU
17629            // list may also be changed.
17630            updateOomAdjLocked();
17631        }
17632        return success;
17633    }
17634
17635    final void updateOomAdjLocked() {
17636        final ActivityRecord TOP_ACT = resumedAppLocked();
17637        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17638        final long now = SystemClock.uptimeMillis();
17639        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
17640        final int N = mLruProcesses.size();
17641
17642        if (false) {
17643            RuntimeException e = new RuntimeException();
17644            e.fillInStackTrace();
17645            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
17646        }
17647
17648        mAdjSeq++;
17649        mNewNumServiceProcs = 0;
17650        mNewNumAServiceProcs = 0;
17651
17652        final int emptyProcessLimit;
17653        final int cachedProcessLimit;
17654        if (mProcessLimit <= 0) {
17655            emptyProcessLimit = cachedProcessLimit = 0;
17656        } else if (mProcessLimit == 1) {
17657            emptyProcessLimit = 1;
17658            cachedProcessLimit = 0;
17659        } else {
17660            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
17661            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
17662        }
17663
17664        // Let's determine how many processes we have running vs.
17665        // how many slots we have for background processes; we may want
17666        // to put multiple processes in a slot of there are enough of
17667        // them.
17668        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
17669                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
17670        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
17671        if (numEmptyProcs > cachedProcessLimit) {
17672            // If there are more empty processes than our limit on cached
17673            // processes, then use the cached process limit for the factor.
17674            // This ensures that the really old empty processes get pushed
17675            // down to the bottom, so if we are running low on memory we will
17676            // have a better chance at keeping around more cached processes
17677            // instead of a gazillion empty processes.
17678            numEmptyProcs = cachedProcessLimit;
17679        }
17680        int emptyFactor = numEmptyProcs/numSlots;
17681        if (emptyFactor < 1) emptyFactor = 1;
17682        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
17683        if (cachedFactor < 1) cachedFactor = 1;
17684        int stepCached = 0;
17685        int stepEmpty = 0;
17686        int numCached = 0;
17687        int numEmpty = 0;
17688        int numTrimming = 0;
17689
17690        mNumNonCachedProcs = 0;
17691        mNumCachedHiddenProcs = 0;
17692
17693        // First update the OOM adjustment for each of the
17694        // application processes based on their current state.
17695        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
17696        int nextCachedAdj = curCachedAdj+1;
17697        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
17698        int nextEmptyAdj = curEmptyAdj+2;
17699        for (int i=N-1; i>=0; i--) {
17700            ProcessRecord app = mLruProcesses.get(i);
17701            if (!app.killedByAm && app.thread != null) {
17702                app.procStateChanged = false;
17703                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
17704
17705                // If we haven't yet assigned the final cached adj
17706                // to the process, do that now.
17707                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
17708                    switch (app.curProcState) {
17709                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
17710                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
17711                            // This process is a cached process holding activities...
17712                            // assign it the next cached value for that type, and then
17713                            // step that cached level.
17714                            app.curRawAdj = curCachedAdj;
17715                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
17716                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
17717                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
17718                                    + ")");
17719                            if (curCachedAdj != nextCachedAdj) {
17720                                stepCached++;
17721                                if (stepCached >= cachedFactor) {
17722                                    stepCached = 0;
17723                                    curCachedAdj = nextCachedAdj;
17724                                    nextCachedAdj += 2;
17725                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
17726                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
17727                                    }
17728                                }
17729                            }
17730                            break;
17731                        default:
17732                            // For everything else, assign next empty cached process
17733                            // level and bump that up.  Note that this means that
17734                            // long-running services that have dropped down to the
17735                            // cached level will be treated as empty (since their process
17736                            // state is still as a service), which is what we want.
17737                            app.curRawAdj = curEmptyAdj;
17738                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
17739                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
17740                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
17741                                    + ")");
17742                            if (curEmptyAdj != nextEmptyAdj) {
17743                                stepEmpty++;
17744                                if (stepEmpty >= emptyFactor) {
17745                                    stepEmpty = 0;
17746                                    curEmptyAdj = nextEmptyAdj;
17747                                    nextEmptyAdj += 2;
17748                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
17749                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
17750                                    }
17751                                }
17752                            }
17753                            break;
17754                    }
17755                }
17756
17757                applyOomAdjLocked(app, TOP_APP, true, now);
17758
17759                // Count the number of process types.
17760                switch (app.curProcState) {
17761                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
17762                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
17763                        mNumCachedHiddenProcs++;
17764                        numCached++;
17765                        if (numCached > cachedProcessLimit) {
17766                            app.kill("cached #" + numCached, true);
17767                        }
17768                        break;
17769                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
17770                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
17771                                && app.lastActivityTime < oldTime) {
17772                            app.kill("empty for "
17773                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
17774                                    / 1000) + "s", true);
17775                        } else {
17776                            numEmpty++;
17777                            if (numEmpty > emptyProcessLimit) {
17778                                app.kill("empty #" + numEmpty, true);
17779                            }
17780                        }
17781                        break;
17782                    default:
17783                        mNumNonCachedProcs++;
17784                        break;
17785                }
17786
17787                if (app.isolated && app.services.size() <= 0) {
17788                    // If this is an isolated process, and there are no
17789                    // services running in it, then the process is no longer
17790                    // needed.  We agressively kill these because we can by
17791                    // definition not re-use the same process again, and it is
17792                    // good to avoid having whatever code was running in them
17793                    // left sitting around after no longer needed.
17794                    app.kill("isolated not needed", true);
17795                }
17796
17797                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
17798                        && !app.killedByAm) {
17799                    numTrimming++;
17800                }
17801            }
17802        }
17803
17804        mNumServiceProcs = mNewNumServiceProcs;
17805
17806        // Now determine the memory trimming level of background processes.
17807        // Unfortunately we need to start at the back of the list to do this
17808        // properly.  We only do this if the number of background apps we
17809        // are managing to keep around is less than half the maximum we desire;
17810        // if we are keeping a good number around, we'll let them use whatever
17811        // memory they want.
17812        final int numCachedAndEmpty = numCached + numEmpty;
17813        int memFactor;
17814        if (numCached <= ProcessList.TRIM_CACHED_APPS
17815                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
17816            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
17817                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
17818            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
17819                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
17820            } else {
17821                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
17822            }
17823        } else {
17824            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
17825        }
17826        // We always allow the memory level to go up (better).  We only allow it to go
17827        // down if we are in a state where that is allowed, *and* the total number of processes
17828        // has gone down since last time.
17829        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
17830                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
17831                + " last=" + mLastNumProcesses);
17832        if (memFactor > mLastMemoryLevel) {
17833            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
17834                memFactor = mLastMemoryLevel;
17835                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
17836            }
17837        }
17838        mLastMemoryLevel = memFactor;
17839        mLastNumProcesses = mLruProcesses.size();
17840        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
17841        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
17842        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
17843            if (mLowRamStartTime == 0) {
17844                mLowRamStartTime = now;
17845            }
17846            int step = 0;
17847            int fgTrimLevel;
17848            switch (memFactor) {
17849                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
17850                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
17851                    break;
17852                case ProcessStats.ADJ_MEM_FACTOR_LOW:
17853                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
17854                    break;
17855                default:
17856                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
17857                    break;
17858            }
17859            int factor = numTrimming/3;
17860            int minFactor = 2;
17861            if (mHomeProcess != null) minFactor++;
17862            if (mPreviousProcess != null) minFactor++;
17863            if (factor < minFactor) factor = minFactor;
17864            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
17865            for (int i=N-1; i>=0; i--) {
17866                ProcessRecord app = mLruProcesses.get(i);
17867                if (allChanged || app.procStateChanged) {
17868                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
17869                    app.procStateChanged = false;
17870                }
17871                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
17872                        && !app.killedByAm) {
17873                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
17874                        try {
17875                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17876                                    "Trimming memory of " + app.processName
17877                                    + " to " + curLevel);
17878                            app.thread.scheduleTrimMemory(curLevel);
17879                        } catch (RemoteException e) {
17880                        }
17881                        if (false) {
17882                            // For now we won't do this; our memory trimming seems
17883                            // to be good enough at this point that destroying
17884                            // activities causes more harm than good.
17885                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
17886                                    && app != mHomeProcess && app != mPreviousProcess) {
17887                                // Need to do this on its own message because the stack may not
17888                                // be in a consistent state at this point.
17889                                // For these apps we will also finish their activities
17890                                // to help them free memory.
17891                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
17892                            }
17893                        }
17894                    }
17895                    app.trimMemoryLevel = curLevel;
17896                    step++;
17897                    if (step >= factor) {
17898                        step = 0;
17899                        switch (curLevel) {
17900                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
17901                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
17902                                break;
17903                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
17904                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
17905                                break;
17906                        }
17907                    }
17908                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
17909                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
17910                            && app.thread != null) {
17911                        try {
17912                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17913                                    "Trimming memory of heavy-weight " + app.processName
17914                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
17915                            app.thread.scheduleTrimMemory(
17916                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
17917                        } catch (RemoteException e) {
17918                        }
17919                    }
17920                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
17921                } else {
17922                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17923                            || app.systemNoUi) && app.pendingUiClean) {
17924                        // If this application is now in the background and it
17925                        // had done UI, then give it the special trim level to
17926                        // have it free UI resources.
17927                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
17928                        if (app.trimMemoryLevel < level && app.thread != null) {
17929                            try {
17930                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17931                                        "Trimming memory of bg-ui " + app.processName
17932                                        + " to " + level);
17933                                app.thread.scheduleTrimMemory(level);
17934                            } catch (RemoteException e) {
17935                            }
17936                        }
17937                        app.pendingUiClean = false;
17938                    }
17939                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
17940                        try {
17941                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17942                                    "Trimming memory of fg " + app.processName
17943                                    + " to " + fgTrimLevel);
17944                            app.thread.scheduleTrimMemory(fgTrimLevel);
17945                        } catch (RemoteException e) {
17946                        }
17947                    }
17948                    app.trimMemoryLevel = fgTrimLevel;
17949                }
17950            }
17951        } else {
17952            if (mLowRamStartTime != 0) {
17953                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
17954                mLowRamStartTime = 0;
17955            }
17956            for (int i=N-1; i>=0; i--) {
17957                ProcessRecord app = mLruProcesses.get(i);
17958                if (allChanged || app.procStateChanged) {
17959                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
17960                    app.procStateChanged = false;
17961                }
17962                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17963                        || app.systemNoUi) && app.pendingUiClean) {
17964                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
17965                            && app.thread != null) {
17966                        try {
17967                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17968                                    "Trimming memory of ui hidden " + app.processName
17969                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
17970                            app.thread.scheduleTrimMemory(
17971                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
17972                        } catch (RemoteException e) {
17973                        }
17974                    }
17975                    app.pendingUiClean = false;
17976                }
17977                app.trimMemoryLevel = 0;
17978            }
17979        }
17980
17981        if (mAlwaysFinishActivities) {
17982            // Need to do this on its own message because the stack may not
17983            // be in a consistent state at this point.
17984            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
17985        }
17986
17987        if (allChanged) {
17988            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
17989        }
17990
17991        if (mProcessStats.shouldWriteNowLocked(now)) {
17992            mHandler.post(new Runnable() {
17993                @Override public void run() {
17994                    synchronized (ActivityManagerService.this) {
17995                        mProcessStats.writeStateAsyncLocked();
17996                    }
17997                }
17998            });
17999        }
18000
18001        if (DEBUG_OOM_ADJ) {
18002            if (false) {
18003                RuntimeException here = new RuntimeException("here");
18004                here.fillInStackTrace();
18005                Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms", here);
18006            } else {
18007                Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
18008            }
18009        }
18010    }
18011
18012    final void trimApplications() {
18013        synchronized (this) {
18014            int i;
18015
18016            // First remove any unused application processes whose package
18017            // has been removed.
18018            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
18019                final ProcessRecord app = mRemovedProcesses.get(i);
18020                if (app.activities.size() == 0
18021                        && app.curReceiver == null && app.services.size() == 0) {
18022                    Slog.i(
18023                        TAG, "Exiting empty application process "
18024                        + app.processName + " ("
18025                        + (app.thread != null ? app.thread.asBinder() : null)
18026                        + ")\n");
18027                    if (app.pid > 0 && app.pid != MY_PID) {
18028                        app.kill("empty", false);
18029                    } else {
18030                        try {
18031                            app.thread.scheduleExit();
18032                        } catch (Exception e) {
18033                            // Ignore exceptions.
18034                        }
18035                    }
18036                    cleanUpApplicationRecordLocked(app, false, true, -1);
18037                    mRemovedProcesses.remove(i);
18038
18039                    if (app.persistent) {
18040                        addAppLocked(app.info, false, null /* ABI override */);
18041                    }
18042                }
18043            }
18044
18045            // Now update the oom adj for all processes.
18046            updateOomAdjLocked();
18047        }
18048    }
18049
18050    /** This method sends the specified signal to each of the persistent apps */
18051    public void signalPersistentProcesses(int sig) throws RemoteException {
18052        if (sig != Process.SIGNAL_USR1) {
18053            throw new SecurityException("Only SIGNAL_USR1 is allowed");
18054        }
18055
18056        synchronized (this) {
18057            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
18058                    != PackageManager.PERMISSION_GRANTED) {
18059                throw new SecurityException("Requires permission "
18060                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
18061            }
18062
18063            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
18064                ProcessRecord r = mLruProcesses.get(i);
18065                if (r.thread != null && r.persistent) {
18066                    Process.sendSignal(r.pid, sig);
18067                }
18068            }
18069        }
18070    }
18071
18072    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
18073        if (proc == null || proc == mProfileProc) {
18074            proc = mProfileProc;
18075            profileType = mProfileType;
18076            clearProfilerLocked();
18077        }
18078        if (proc == null) {
18079            return;
18080        }
18081        try {
18082            proc.thread.profilerControl(false, null, profileType);
18083        } catch (RemoteException e) {
18084            throw new IllegalStateException("Process disappeared");
18085        }
18086    }
18087
18088    private void clearProfilerLocked() {
18089        if (mProfileFd != null) {
18090            try {
18091                mProfileFd.close();
18092            } catch (IOException e) {
18093            }
18094        }
18095        mProfileApp = null;
18096        mProfileProc = null;
18097        mProfileFile = null;
18098        mProfileType = 0;
18099        mAutoStopProfiler = false;
18100        mSamplingInterval = 0;
18101    }
18102
18103    public boolean profileControl(String process, int userId, boolean start,
18104            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
18105
18106        try {
18107            synchronized (this) {
18108                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
18109                // its own permission.
18110                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
18111                        != PackageManager.PERMISSION_GRANTED) {
18112                    throw new SecurityException("Requires permission "
18113                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
18114                }
18115
18116                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
18117                    throw new IllegalArgumentException("null profile info or fd");
18118                }
18119
18120                ProcessRecord proc = null;
18121                if (process != null) {
18122                    proc = findProcessLocked(process, userId, "profileControl");
18123                }
18124
18125                if (start && (proc == null || proc.thread == null)) {
18126                    throw new IllegalArgumentException("Unknown process: " + process);
18127                }
18128
18129                if (start) {
18130                    stopProfilerLocked(null, 0);
18131                    setProfileApp(proc.info, proc.processName, profilerInfo);
18132                    mProfileProc = proc;
18133                    mProfileType = profileType;
18134                    ParcelFileDescriptor fd = profilerInfo.profileFd;
18135                    try {
18136                        fd = fd.dup();
18137                    } catch (IOException e) {
18138                        fd = null;
18139                    }
18140                    profilerInfo.profileFd = fd;
18141                    proc.thread.profilerControl(start, profilerInfo, profileType);
18142                    fd = null;
18143                    mProfileFd = null;
18144                } else {
18145                    stopProfilerLocked(proc, profileType);
18146                    if (profilerInfo != null && profilerInfo.profileFd != null) {
18147                        try {
18148                            profilerInfo.profileFd.close();
18149                        } catch (IOException e) {
18150                        }
18151                    }
18152                }
18153
18154                return true;
18155            }
18156        } catch (RemoteException e) {
18157            throw new IllegalStateException("Process disappeared");
18158        } finally {
18159            if (profilerInfo != null && profilerInfo.profileFd != null) {
18160                try {
18161                    profilerInfo.profileFd.close();
18162                } catch (IOException e) {
18163                }
18164            }
18165        }
18166    }
18167
18168    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
18169        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18170                userId, true, ALLOW_FULL_ONLY, callName, null);
18171        ProcessRecord proc = null;
18172        try {
18173            int pid = Integer.parseInt(process);
18174            synchronized (mPidsSelfLocked) {
18175                proc = mPidsSelfLocked.get(pid);
18176            }
18177        } catch (NumberFormatException e) {
18178        }
18179
18180        if (proc == null) {
18181            ArrayMap<String, SparseArray<ProcessRecord>> all
18182                    = mProcessNames.getMap();
18183            SparseArray<ProcessRecord> procs = all.get(process);
18184            if (procs != null && procs.size() > 0) {
18185                proc = procs.valueAt(0);
18186                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
18187                    for (int i=1; i<procs.size(); i++) {
18188                        ProcessRecord thisProc = procs.valueAt(i);
18189                        if (thisProc.userId == userId) {
18190                            proc = thisProc;
18191                            break;
18192                        }
18193                    }
18194                }
18195            }
18196        }
18197
18198        return proc;
18199    }
18200
18201    public boolean dumpHeap(String process, int userId, boolean managed,
18202            String path, ParcelFileDescriptor fd) throws RemoteException {
18203
18204        try {
18205            synchronized (this) {
18206                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
18207                // its own permission (same as profileControl).
18208                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
18209                        != PackageManager.PERMISSION_GRANTED) {
18210                    throw new SecurityException("Requires permission "
18211                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
18212                }
18213
18214                if (fd == null) {
18215                    throw new IllegalArgumentException("null fd");
18216                }
18217
18218                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
18219                if (proc == null || proc.thread == null) {
18220                    throw new IllegalArgumentException("Unknown process: " + process);
18221                }
18222
18223                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
18224                if (!isDebuggable) {
18225                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
18226                        throw new SecurityException("Process not debuggable: " + proc);
18227                    }
18228                }
18229
18230                proc.thread.dumpHeap(managed, path, fd);
18231                fd = null;
18232                return true;
18233            }
18234        } catch (RemoteException e) {
18235            throw new IllegalStateException("Process disappeared");
18236        } finally {
18237            if (fd != null) {
18238                try {
18239                    fd.close();
18240                } catch (IOException e) {
18241                }
18242            }
18243        }
18244    }
18245
18246    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
18247    public void monitor() {
18248        synchronized (this) { }
18249    }
18250
18251    void onCoreSettingsChange(Bundle settings) {
18252        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
18253            ProcessRecord processRecord = mLruProcesses.get(i);
18254            try {
18255                if (processRecord.thread != null) {
18256                    processRecord.thread.setCoreSettings(settings);
18257                }
18258            } catch (RemoteException re) {
18259                /* ignore */
18260            }
18261        }
18262    }
18263
18264    // Multi-user methods
18265
18266    /**
18267     * Start user, if its not already running, but don't bring it to foreground.
18268     */
18269    @Override
18270    public boolean startUserInBackground(final int userId) {
18271        return startUser(userId, /* foreground */ false);
18272    }
18273
18274    /**
18275     * Start user, if its not already running, and bring it to foreground.
18276     */
18277    boolean startUserInForeground(final int userId, Dialog dlg) {
18278        boolean result = startUser(userId, /* foreground */ true);
18279        dlg.dismiss();
18280        return result;
18281    }
18282
18283    /**
18284     * Refreshes the list of users related to the current user when either a
18285     * user switch happens or when a new related user is started in the
18286     * background.
18287     */
18288    private void updateCurrentProfileIdsLocked() {
18289        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18290                mCurrentUserId, false /* enabledOnly */);
18291        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
18292        for (int i = 0; i < currentProfileIds.length; i++) {
18293            currentProfileIds[i] = profiles.get(i).id;
18294        }
18295        mCurrentProfileIds = currentProfileIds;
18296
18297        synchronized (mUserProfileGroupIdsSelfLocked) {
18298            mUserProfileGroupIdsSelfLocked.clear();
18299            final List<UserInfo> users = getUserManagerLocked().getUsers(false);
18300            for (int i = 0; i < users.size(); i++) {
18301                UserInfo user = users.get(i);
18302                if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
18303                    mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
18304                }
18305            }
18306        }
18307    }
18308
18309    private Set getProfileIdsLocked(int userId) {
18310        Set userIds = new HashSet<Integer>();
18311        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18312                userId, false /* enabledOnly */);
18313        for (UserInfo user : profiles) {
18314            userIds.add(Integer.valueOf(user.id));
18315        }
18316        return userIds;
18317    }
18318
18319    @Override
18320    public boolean switchUser(final int userId) {
18321        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
18322        String userName;
18323        synchronized (this) {
18324            UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18325            if (userInfo == null) {
18326                Slog.w(TAG, "No user info for user #" + userId);
18327                return false;
18328            }
18329            if (userInfo.isManagedProfile()) {
18330                Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18331                return false;
18332            }
18333            userName = userInfo.name;
18334            mTargetUserId = userId;
18335        }
18336        mHandler.removeMessages(START_USER_SWITCH_MSG);
18337        mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName));
18338        return true;
18339    }
18340
18341    private void showUserSwitchDialog(int userId, String userName) {
18342        // The dialog will show and then initiate the user switch by calling startUserInForeground
18343        Dialog d = new UserSwitchingDialog(this, mContext, userId, userName,
18344                true /* above system */);
18345        d.show();
18346    }
18347
18348    private boolean startUser(final int userId, final boolean foreground) {
18349        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18350                != PackageManager.PERMISSION_GRANTED) {
18351            String msg = "Permission Denial: switchUser() from pid="
18352                    + Binder.getCallingPid()
18353                    + ", uid=" + Binder.getCallingUid()
18354                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18355            Slog.w(TAG, msg);
18356            throw new SecurityException(msg);
18357        }
18358
18359        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
18360
18361        final long ident = Binder.clearCallingIdentity();
18362        try {
18363            synchronized (this) {
18364                final int oldUserId = mCurrentUserId;
18365                if (oldUserId == userId) {
18366                    return true;
18367                }
18368
18369                mStackSupervisor.setLockTaskModeLocked(null, false);
18370
18371                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18372                if (userInfo == null) {
18373                    Slog.w(TAG, "No user info for user #" + userId);
18374                    return false;
18375                }
18376                if (foreground && userInfo.isManagedProfile()) {
18377                    Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18378                    return false;
18379                }
18380
18381                if (foreground) {
18382                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
18383                            R.anim.screen_user_enter);
18384                }
18385
18386                boolean needStart = false;
18387
18388                // If the user we are switching to is not currently started, then
18389                // we need to start it now.
18390                if (mStartedUsers.get(userId) == null) {
18391                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
18392                    updateStartedUserArrayLocked();
18393                    needStart = true;
18394                }
18395
18396                final Integer userIdInt = Integer.valueOf(userId);
18397                mUserLru.remove(userIdInt);
18398                mUserLru.add(userIdInt);
18399
18400                if (foreground) {
18401                    mCurrentUserId = userId;
18402                    mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up
18403                    updateCurrentProfileIdsLocked();
18404                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
18405                    // Once the internal notion of the active user has switched, we lock the device
18406                    // with the option to show the user switcher on the keyguard.
18407                    mWindowManager.lockNow(null);
18408                } else {
18409                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
18410                    updateCurrentProfileIdsLocked();
18411                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
18412                    mUserLru.remove(currentUserIdInt);
18413                    mUserLru.add(currentUserIdInt);
18414                }
18415
18416                final UserStartedState uss = mStartedUsers.get(userId);
18417
18418                // Make sure user is in the started state.  If it is currently
18419                // stopping, we need to knock that off.
18420                if (uss.mState == UserStartedState.STATE_STOPPING) {
18421                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
18422                    // so we can just fairly silently bring the user back from
18423                    // the almost-dead.
18424                    uss.mState = UserStartedState.STATE_RUNNING;
18425                    updateStartedUserArrayLocked();
18426                    needStart = true;
18427                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
18428                    // This means ACTION_SHUTDOWN has been sent, so we will
18429                    // need to treat this as a new boot of the user.
18430                    uss.mState = UserStartedState.STATE_BOOTING;
18431                    updateStartedUserArrayLocked();
18432                    needStart = true;
18433                }
18434
18435                if (uss.mState == UserStartedState.STATE_BOOTING) {
18436                    // Booting up a new user, need to tell system services about it.
18437                    // Note that this is on the same handler as scheduling of broadcasts,
18438                    // which is important because it needs to go first.
18439                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
18440                }
18441
18442                if (foreground) {
18443                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
18444                            oldUserId));
18445                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
18446                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18447                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
18448                            oldUserId, userId, uss));
18449                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
18450                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
18451                }
18452
18453                if (needStart) {
18454                    // Send USER_STARTED broadcast
18455                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
18456                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18457                            | Intent.FLAG_RECEIVER_FOREGROUND);
18458                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18459                    broadcastIntentLocked(null, null, intent,
18460                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18461                            false, false, MY_PID, Process.SYSTEM_UID, userId);
18462                }
18463
18464                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
18465                    if (userId != UserHandle.USER_OWNER) {
18466                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
18467                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18468                        broadcastIntentLocked(null, null, intent, null,
18469                                new IIntentReceiver.Stub() {
18470                                    public void performReceive(Intent intent, int resultCode,
18471                                            String data, Bundle extras, boolean ordered,
18472                                            boolean sticky, int sendingUser) {
18473                                        onUserInitialized(uss, foreground, oldUserId, userId);
18474                                    }
18475                                }, 0, null, null, null, AppOpsManager.OP_NONE,
18476                                true, false, MY_PID, Process.SYSTEM_UID,
18477                                userId);
18478                        uss.initializing = true;
18479                    } else {
18480                        getUserManagerLocked().makeInitialized(userInfo.id);
18481                    }
18482                }
18483
18484                if (foreground) {
18485                    if (!uss.initializing) {
18486                        moveUserToForeground(uss, oldUserId, userId);
18487                    }
18488                } else {
18489                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
18490                }
18491
18492                if (needStart) {
18493                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
18494                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18495                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18496                    broadcastIntentLocked(null, null, intent,
18497                            null, new IIntentReceiver.Stub() {
18498                                @Override
18499                                public void performReceive(Intent intent, int resultCode, String data,
18500                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
18501                                        throws RemoteException {
18502                                }
18503                            }, 0, null, null,
18504                            INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
18505                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18506                }
18507            }
18508        } finally {
18509            Binder.restoreCallingIdentity(ident);
18510        }
18511
18512        return true;
18513    }
18514
18515    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
18516        long ident = Binder.clearCallingIdentity();
18517        try {
18518            Intent intent;
18519            if (oldUserId >= 0) {
18520                // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
18521                List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
18522                int count = profiles.size();
18523                for (int i = 0; i < count; i++) {
18524                    int profileUserId = profiles.get(i).id;
18525                    intent = new Intent(Intent.ACTION_USER_BACKGROUND);
18526                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18527                            | Intent.FLAG_RECEIVER_FOREGROUND);
18528                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18529                    broadcastIntentLocked(null, null, intent,
18530                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18531                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18532                }
18533            }
18534            if (newUserId >= 0) {
18535                // Send USER_FOREGROUND broadcast to all profiles of the incoming user
18536                List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
18537                int count = profiles.size();
18538                for (int i = 0; i < count; i++) {
18539                    int profileUserId = profiles.get(i).id;
18540                    intent = new Intent(Intent.ACTION_USER_FOREGROUND);
18541                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18542                            | Intent.FLAG_RECEIVER_FOREGROUND);
18543                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18544                    broadcastIntentLocked(null, null, intent,
18545                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18546                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18547                }
18548                intent = new Intent(Intent.ACTION_USER_SWITCHED);
18549                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18550                        | Intent.FLAG_RECEIVER_FOREGROUND);
18551                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
18552                broadcastIntentLocked(null, null, intent,
18553                        null, null, 0, null, null,
18554                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
18555                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18556            }
18557        } finally {
18558            Binder.restoreCallingIdentity(ident);
18559        }
18560    }
18561
18562    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
18563            final int newUserId) {
18564        final int N = mUserSwitchObservers.beginBroadcast();
18565        if (N > 0) {
18566            final IRemoteCallback callback = new IRemoteCallback.Stub() {
18567                int mCount = 0;
18568                @Override
18569                public void sendResult(Bundle data) throws RemoteException {
18570                    synchronized (ActivityManagerService.this) {
18571                        if (mCurUserSwitchCallback == this) {
18572                            mCount++;
18573                            if (mCount == N) {
18574                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18575                            }
18576                        }
18577                    }
18578                }
18579            };
18580            synchronized (this) {
18581                uss.switching = true;
18582                mCurUserSwitchCallback = callback;
18583            }
18584            for (int i=0; i<N; i++) {
18585                try {
18586                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
18587                            newUserId, callback);
18588                } catch (RemoteException e) {
18589                }
18590            }
18591        } else {
18592            synchronized (this) {
18593                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18594            }
18595        }
18596        mUserSwitchObservers.finishBroadcast();
18597    }
18598
18599    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18600        synchronized (this) {
18601            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
18602            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18603        }
18604    }
18605
18606    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
18607        mCurUserSwitchCallback = null;
18608        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18609        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
18610                oldUserId, newUserId, uss));
18611    }
18612
18613    void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) {
18614        synchronized (this) {
18615            if (foreground) {
18616                moveUserToForeground(uss, oldUserId, newUserId);
18617            }
18618        }
18619
18620        completeSwitchAndInitalize(uss, newUserId, true, false);
18621    }
18622
18623    void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) {
18624        boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss);
18625        if (homeInFront) {
18626            startHomeActivityLocked(newUserId);
18627        } else {
18628            mStackSupervisor.resumeTopActivitiesLocked();
18629        }
18630        EventLogTags.writeAmSwitchUser(newUserId);
18631        getUserManagerLocked().userForeground(newUserId);
18632        sendUserSwitchBroadcastsLocked(oldUserId, newUserId);
18633    }
18634
18635    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18636        completeSwitchAndInitalize(uss, newUserId, false, true);
18637    }
18638
18639    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
18640            boolean clearInitializing, boolean clearSwitching) {
18641        boolean unfrozen = false;
18642        synchronized (this) {
18643            if (clearInitializing) {
18644                uss.initializing = false;
18645                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
18646            }
18647            if (clearSwitching) {
18648                uss.switching = false;
18649            }
18650            if (!uss.switching && !uss.initializing) {
18651                mWindowManager.stopFreezingScreen();
18652                unfrozen = true;
18653            }
18654        }
18655        if (unfrozen) {
18656            final int N = mUserSwitchObservers.beginBroadcast();
18657            for (int i=0; i<N; i++) {
18658                try {
18659                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
18660                } catch (RemoteException e) {
18661                }
18662            }
18663            mUserSwitchObservers.finishBroadcast();
18664        }
18665        stopGuestUserIfBackground();
18666    }
18667
18668    /**
18669     * Stops the guest user if it has gone to the background.
18670     */
18671    private void stopGuestUserIfBackground() {
18672        synchronized (this) {
18673            final int num = mUserLru.size();
18674            for (int i = 0; i < num; i++) {
18675                Integer oldUserId = mUserLru.get(i);
18676                UserStartedState oldUss = mStartedUsers.get(oldUserId);
18677                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId
18678                        || oldUss.mState == UserStartedState.STATE_STOPPING
18679                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
18680                    continue;
18681                }
18682                UserInfo userInfo = mUserManager.getUserInfo(oldUserId);
18683                if (userInfo.isGuest()) {
18684                    // This is a user to be stopped.
18685                    stopUserLocked(oldUserId, null);
18686                    break;
18687                }
18688            }
18689        }
18690    }
18691
18692    void scheduleStartProfilesLocked() {
18693        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
18694            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
18695                    DateUtils.SECOND_IN_MILLIS);
18696        }
18697    }
18698
18699    void startProfilesLocked() {
18700        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
18701        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18702                mCurrentUserId, false /* enabledOnly */);
18703        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
18704        for (UserInfo user : profiles) {
18705            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
18706                    && user.id != mCurrentUserId) {
18707                toStart.add(user);
18708            }
18709        }
18710        final int n = toStart.size();
18711        int i = 0;
18712        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
18713            startUserInBackground(toStart.get(i).id);
18714        }
18715        if (i < n) {
18716            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
18717        }
18718    }
18719
18720    void finishUserBoot(UserStartedState uss) {
18721        synchronized (this) {
18722            if (uss.mState == UserStartedState.STATE_BOOTING
18723                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
18724                uss.mState = UserStartedState.STATE_RUNNING;
18725                final int userId = uss.mHandle.getIdentifier();
18726                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
18727                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18728                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
18729                broadcastIntentLocked(null, null, intent,
18730                        null, null, 0, null, null,
18731                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
18732                        true, false, MY_PID, Process.SYSTEM_UID, userId);
18733            }
18734        }
18735    }
18736
18737    void finishUserSwitch(UserStartedState uss) {
18738        synchronized (this) {
18739            finishUserBoot(uss);
18740
18741            startProfilesLocked();
18742
18743            int num = mUserLru.size();
18744            int i = 0;
18745            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
18746                Integer oldUserId = mUserLru.get(i);
18747                UserStartedState oldUss = mStartedUsers.get(oldUserId);
18748                if (oldUss == null) {
18749                    // Shouldn't happen, but be sane if it does.
18750                    mUserLru.remove(i);
18751                    num--;
18752                    continue;
18753                }
18754                if (oldUss.mState == UserStartedState.STATE_STOPPING
18755                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
18756                    // This user is already stopping, doesn't count.
18757                    num--;
18758                    i++;
18759                    continue;
18760                }
18761                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
18762                    // Owner and current can't be stopped, but count as running.
18763                    i++;
18764                    continue;
18765                }
18766                // This is a user to be stopped.
18767                stopUserLocked(oldUserId, null);
18768                num--;
18769                i++;
18770            }
18771        }
18772    }
18773
18774    @Override
18775    public int stopUser(final int userId, final IStopUserCallback callback) {
18776        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18777                != PackageManager.PERMISSION_GRANTED) {
18778            String msg = "Permission Denial: switchUser() from pid="
18779                    + Binder.getCallingPid()
18780                    + ", uid=" + Binder.getCallingUid()
18781                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18782            Slog.w(TAG, msg);
18783            throw new SecurityException(msg);
18784        }
18785        if (userId <= 0) {
18786            throw new IllegalArgumentException("Can't stop primary user " + userId);
18787        }
18788        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
18789        synchronized (this) {
18790            return stopUserLocked(userId, callback);
18791        }
18792    }
18793
18794    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
18795        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
18796        if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) {
18797            return ActivityManager.USER_OP_IS_CURRENT;
18798        }
18799
18800        final UserStartedState uss = mStartedUsers.get(userId);
18801        if (uss == null) {
18802            // User is not started, nothing to do...  but we do need to
18803            // callback if requested.
18804            if (callback != null) {
18805                mHandler.post(new Runnable() {
18806                    @Override
18807                    public void run() {
18808                        try {
18809                            callback.userStopped(userId);
18810                        } catch (RemoteException e) {
18811                        }
18812                    }
18813                });
18814            }
18815            return ActivityManager.USER_OP_SUCCESS;
18816        }
18817
18818        if (callback != null) {
18819            uss.mStopCallbacks.add(callback);
18820        }
18821
18822        if (uss.mState != UserStartedState.STATE_STOPPING
18823                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18824            uss.mState = UserStartedState.STATE_STOPPING;
18825            updateStartedUserArrayLocked();
18826
18827            long ident = Binder.clearCallingIdentity();
18828            try {
18829                // We are going to broadcast ACTION_USER_STOPPING and then
18830                // once that is done send a final ACTION_SHUTDOWN and then
18831                // stop the user.
18832                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
18833                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18834                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18835                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
18836                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
18837                // This is the result receiver for the final shutdown broadcast.
18838                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
18839                    @Override
18840                    public void performReceive(Intent intent, int resultCode, String data,
18841                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
18842                        finishUserStop(uss);
18843                    }
18844                };
18845                // This is the result receiver for the initial stopping broadcast.
18846                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
18847                    @Override
18848                    public void performReceive(Intent intent, int resultCode, String data,
18849                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
18850                        // On to the next.
18851                        synchronized (ActivityManagerService.this) {
18852                            if (uss.mState != UserStartedState.STATE_STOPPING) {
18853                                // Whoops, we are being started back up.  Abort, abort!
18854                                return;
18855                            }
18856                            uss.mState = UserStartedState.STATE_SHUTDOWN;
18857                        }
18858                        mBatteryStatsService.noteEvent(
18859                                BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
18860                                Integer.toString(userId), userId);
18861                        mSystemServiceManager.stopUser(userId);
18862                        broadcastIntentLocked(null, null, shutdownIntent,
18863                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
18864                                true, false, MY_PID, Process.SYSTEM_UID, userId);
18865                    }
18866                };
18867                // Kick things off.
18868                broadcastIntentLocked(null, null, stoppingIntent,
18869                        null, stoppingReceiver, 0, null, null,
18870                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
18871                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18872            } finally {
18873                Binder.restoreCallingIdentity(ident);
18874            }
18875        }
18876
18877        return ActivityManager.USER_OP_SUCCESS;
18878    }
18879
18880    void finishUserStop(UserStartedState uss) {
18881        final int userId = uss.mHandle.getIdentifier();
18882        boolean stopped;
18883        ArrayList<IStopUserCallback> callbacks;
18884        synchronized (this) {
18885            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
18886            if (mStartedUsers.get(userId) != uss) {
18887                stopped = false;
18888            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
18889                stopped = false;
18890            } else {
18891                stopped = true;
18892                // User can no longer run.
18893                mStartedUsers.remove(userId);
18894                mUserLru.remove(Integer.valueOf(userId));
18895                updateStartedUserArrayLocked();
18896
18897                // Clean up all state and processes associated with the user.
18898                // Kill all the processes for the user.
18899                forceStopUserLocked(userId, "finish user");
18900            }
18901
18902            // Explicitly remove the old information in mRecentTasks.
18903            mRecentTasks.removeTasksForUserLocked(userId);
18904        }
18905
18906        for (int i=0; i<callbacks.size(); i++) {
18907            try {
18908                if (stopped) callbacks.get(i).userStopped(userId);
18909                else callbacks.get(i).userStopAborted(userId);
18910            } catch (RemoteException e) {
18911            }
18912        }
18913
18914        if (stopped) {
18915            mSystemServiceManager.cleanupUser(userId);
18916            synchronized (this) {
18917                mStackSupervisor.removeUserLocked(userId);
18918            }
18919        }
18920    }
18921
18922    @Override
18923    public UserInfo getCurrentUser() {
18924        if ((checkCallingPermission(INTERACT_ACROSS_USERS)
18925                != PackageManager.PERMISSION_GRANTED) && (
18926                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18927                != PackageManager.PERMISSION_GRANTED)) {
18928            String msg = "Permission Denial: getCurrentUser() from pid="
18929                    + Binder.getCallingPid()
18930                    + ", uid=" + Binder.getCallingUid()
18931                    + " requires " + INTERACT_ACROSS_USERS;
18932            Slog.w(TAG, msg);
18933            throw new SecurityException(msg);
18934        }
18935        synchronized (this) {
18936            int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
18937            return getUserManagerLocked().getUserInfo(userId);
18938        }
18939    }
18940
18941    int getCurrentUserIdLocked() {
18942        return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
18943    }
18944
18945    @Override
18946    public boolean isUserRunning(int userId, boolean orStopped) {
18947        if (checkCallingPermission(INTERACT_ACROSS_USERS)
18948                != PackageManager.PERMISSION_GRANTED) {
18949            String msg = "Permission Denial: isUserRunning() from pid="
18950                    + Binder.getCallingPid()
18951                    + ", uid=" + Binder.getCallingUid()
18952                    + " requires " + INTERACT_ACROSS_USERS;
18953            Slog.w(TAG, msg);
18954            throw new SecurityException(msg);
18955        }
18956        synchronized (this) {
18957            return isUserRunningLocked(userId, orStopped);
18958        }
18959    }
18960
18961    boolean isUserRunningLocked(int userId, boolean orStopped) {
18962        UserStartedState state = mStartedUsers.get(userId);
18963        if (state == null) {
18964            return false;
18965        }
18966        if (orStopped) {
18967            return true;
18968        }
18969        return state.mState != UserStartedState.STATE_STOPPING
18970                && state.mState != UserStartedState.STATE_SHUTDOWN;
18971    }
18972
18973    @Override
18974    public int[] getRunningUserIds() {
18975        if (checkCallingPermission(INTERACT_ACROSS_USERS)
18976                != PackageManager.PERMISSION_GRANTED) {
18977            String msg = "Permission Denial: isUserRunning() from pid="
18978                    + Binder.getCallingPid()
18979                    + ", uid=" + Binder.getCallingUid()
18980                    + " requires " + INTERACT_ACROSS_USERS;
18981            Slog.w(TAG, msg);
18982            throw new SecurityException(msg);
18983        }
18984        synchronized (this) {
18985            return mStartedUserArray;
18986        }
18987    }
18988
18989    private void updateStartedUserArrayLocked() {
18990        int num = 0;
18991        for (int i=0; i<mStartedUsers.size();  i++) {
18992            UserStartedState uss = mStartedUsers.valueAt(i);
18993            // This list does not include stopping users.
18994            if (uss.mState != UserStartedState.STATE_STOPPING
18995                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18996                num++;
18997            }
18998        }
18999        mStartedUserArray = new int[num];
19000        num = 0;
19001        for (int i=0; i<mStartedUsers.size();  i++) {
19002            UserStartedState uss = mStartedUsers.valueAt(i);
19003            if (uss.mState != UserStartedState.STATE_STOPPING
19004                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
19005                mStartedUserArray[num] = mStartedUsers.keyAt(i);
19006                num++;
19007            }
19008        }
19009    }
19010
19011    @Override
19012    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
19013        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
19014                != PackageManager.PERMISSION_GRANTED) {
19015            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
19016                    + Binder.getCallingPid()
19017                    + ", uid=" + Binder.getCallingUid()
19018                    + " requires " + INTERACT_ACROSS_USERS_FULL;
19019            Slog.w(TAG, msg);
19020            throw new SecurityException(msg);
19021        }
19022
19023        mUserSwitchObservers.register(observer);
19024    }
19025
19026    @Override
19027    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
19028        mUserSwitchObservers.unregister(observer);
19029    }
19030
19031    private boolean userExists(int userId) {
19032        if (userId == 0) {
19033            return true;
19034        }
19035        UserManagerService ums = getUserManagerLocked();
19036        return ums != null ? (ums.getUserInfo(userId) != null) : false;
19037    }
19038
19039    int[] getUsersLocked() {
19040        UserManagerService ums = getUserManagerLocked();
19041        return ums != null ? ums.getUserIds() : new int[] { 0 };
19042    }
19043
19044    UserManagerService getUserManagerLocked() {
19045        if (mUserManager == null) {
19046            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
19047            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
19048        }
19049        return mUserManager;
19050    }
19051
19052    private int applyUserId(int uid, int userId) {
19053        return UserHandle.getUid(userId, uid);
19054    }
19055
19056    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
19057        if (info == null) return null;
19058        ApplicationInfo newInfo = new ApplicationInfo(info);
19059        newInfo.uid = applyUserId(info.uid, userId);
19060        newInfo.dataDir = USER_DATA_DIR + userId + "/"
19061                + info.packageName;
19062        return newInfo;
19063    }
19064
19065    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
19066        if (aInfo == null
19067                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
19068            return aInfo;
19069        }
19070
19071        ActivityInfo info = new ActivityInfo(aInfo);
19072        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
19073        return info;
19074    }
19075
19076    private final class LocalService extends ActivityManagerInternal {
19077        @Override
19078        public void onWakefulnessChanged(int wakefulness) {
19079            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
19080        }
19081
19082        @Override
19083        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
19084                String processName, String abiOverride, int uid, Runnable crashHandler) {
19085            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
19086                    processName, abiOverride, uid, crashHandler);
19087        }
19088    }
19089
19090    /**
19091     * An implementation of IAppTask, that allows an app to manage its own tasks via
19092     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
19093     * only the process that calls getAppTasks() can call the AppTask methods.
19094     */
19095    class AppTaskImpl extends IAppTask.Stub {
19096        private int mTaskId;
19097        private int mCallingUid;
19098
19099        public AppTaskImpl(int taskId, int callingUid) {
19100            mTaskId = taskId;
19101            mCallingUid = callingUid;
19102        }
19103
19104        private void checkCaller() {
19105            if (mCallingUid != Binder.getCallingUid()) {
19106                throw new SecurityException("Caller " + mCallingUid
19107                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
19108            }
19109        }
19110
19111        @Override
19112        public void finishAndRemoveTask() {
19113            checkCaller();
19114
19115            synchronized (ActivityManagerService.this) {
19116                long origId = Binder.clearCallingIdentity();
19117                try {
19118                    if (!removeTaskByIdLocked(mTaskId, false)) {
19119                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19120                    }
19121                } finally {
19122                    Binder.restoreCallingIdentity(origId);
19123                }
19124            }
19125        }
19126
19127        @Override
19128        public ActivityManager.RecentTaskInfo getTaskInfo() {
19129            checkCaller();
19130
19131            synchronized (ActivityManagerService.this) {
19132                long origId = Binder.clearCallingIdentity();
19133                try {
19134                    TaskRecord tr = mRecentTasks.taskForIdLocked(mTaskId);
19135                    if (tr == null) {
19136                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19137                    }
19138                    return createRecentTaskInfoFromTaskRecord(tr);
19139                } finally {
19140                    Binder.restoreCallingIdentity(origId);
19141                }
19142            }
19143        }
19144
19145        @Override
19146        public void moveToFront() {
19147            checkCaller();
19148            // Will bring task to front if it already has a root activity.
19149            startActivityFromRecentsInner(mTaskId, null);
19150        }
19151
19152        @Override
19153        public int startActivity(IBinder whoThread, String callingPackage,
19154                Intent intent, String resolvedType, Bundle options) {
19155            checkCaller();
19156
19157            int callingUser = UserHandle.getCallingUserId();
19158            TaskRecord tr;
19159            IApplicationThread appThread;
19160            synchronized (ActivityManagerService.this) {
19161                tr = mRecentTasks.taskForIdLocked(mTaskId);
19162                if (tr == null) {
19163                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19164                }
19165                appThread = ApplicationThreadNative.asInterface(whoThread);
19166                if (appThread == null) {
19167                    throw new IllegalArgumentException("Bad app thread " + appThread);
19168                }
19169            }
19170            return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent,
19171                    resolvedType, null, null, null, null, 0, 0, null, null,
19172                    null, options, callingUser, null, tr);
19173        }
19174
19175        @Override
19176        public void setExcludeFromRecents(boolean exclude) {
19177            checkCaller();
19178
19179            synchronized (ActivityManagerService.this) {
19180                long origId = Binder.clearCallingIdentity();
19181                try {
19182                    TaskRecord tr = mRecentTasks.taskForIdLocked(mTaskId);
19183                    if (tr == null) {
19184                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19185                    }
19186                    Intent intent = tr.getBaseIntent();
19187                    if (exclude) {
19188                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
19189                    } else {
19190                        intent.setFlags(intent.getFlags()
19191                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
19192                    }
19193                } finally {
19194                    Binder.restoreCallingIdentity(origId);
19195                }
19196            }
19197        }
19198    }
19199}
19200