OSDN Git Service

Merge "Don't drop runtime permissions on older system app update." into mnc-dev
[android-x86/frameworks-base.git] / services / core / java / com / android / server / am / ActivityManagerService.java
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
17 package com.android.server.am;
18
19 import static android.Manifest.permission.INTERACT_ACROSS_USERS;
20 import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
21 import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
22 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
23 import static com.android.internal.util.XmlUtils.readBooleanAttribute;
24 import static com.android.internal.util.XmlUtils.readIntAttribute;
25 import static com.android.internal.util.XmlUtils.readLongAttribute;
26 import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
27 import static com.android.internal.util.XmlUtils.writeIntAttribute;
28 import static com.android.internal.util.XmlUtils.writeLongAttribute;
29 import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST;
30 import static com.android.server.am.ActivityManagerDebugConfig.*;
31 import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
32 import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
33 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
34 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
35 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE;
36 import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
37 import static org.xmlpull.v1.XmlPullParser.START_TAG;
38
39 import android.Manifest;
40 import android.app.AppOpsManager;
41 import android.app.ApplicationThreadNative;
42 import android.app.BroadcastOptions;
43 import android.app.IActivityContainer;
44 import android.app.IActivityContainerCallback;
45 import android.app.IAppTask;
46 import android.app.ITaskStackListener;
47 import android.app.ProfilerInfo;
48 import android.app.assist.AssistContent;
49 import android.app.assist.AssistStructure;
50 import android.app.usage.UsageEvents;
51 import android.app.usage.UsageStatsManagerInternal;
52 import android.appwidget.AppWidgetManager;
53 import android.content.pm.PermissionInfo;
54 import android.content.res.Resources;
55 import android.graphics.Bitmap;
56 import android.graphics.Point;
57 import android.graphics.Rect;
58 import android.os.BatteryStats;
59 import android.os.PersistableBundle;
60 import android.os.PowerManager;
61 import android.os.Trace;
62 import android.os.TransactionTooLargeException;
63 import android.os.WorkSource;
64 import android.os.storage.IMountService;
65 import android.os.storage.MountServiceInternal;
66 import android.os.storage.StorageManager;
67 import android.service.voice.IVoiceInteractionSession;
68 import android.service.voice.VoiceInteractionSession;
69 import android.util.ArrayMap;
70 import android.util.ArraySet;
71 import android.util.DebugUtils;
72 import android.util.SparseIntArray;
73 import android.view.Display;
74
75 import com.android.internal.R;
76 import com.android.internal.annotations.GuardedBy;
77 import com.android.internal.app.AssistUtils;
78 import com.android.internal.app.DumpHeapActivity;
79 import com.android.internal.app.IAppOpsService;
80 import com.android.internal.app.IVoiceInteractor;
81 import com.android.internal.app.ProcessMap;
82 import com.android.internal.app.ProcessStats;
83 import com.android.internal.os.BackgroundThread;
84 import com.android.internal.os.BatteryStatsImpl;
85 import com.android.internal.os.IResultReceiver;
86 import com.android.internal.os.ProcessCpuTracker;
87 import com.android.internal.os.TransferPipe;
88 import com.android.internal.os.Zygote;
89 import com.android.internal.util.ArrayUtils;
90 import com.android.internal.util.FastPrintWriter;
91 import com.android.internal.util.FastXmlSerializer;
92 import com.android.internal.util.MemInfoReader;
93 import com.android.internal.util.Preconditions;
94 import com.android.server.AppOpsService;
95 import com.android.server.AttributeCache;
96 import com.android.server.DeviceIdleController;
97 import com.android.server.IntentResolver;
98 import com.android.server.LocalServices;
99 import com.android.server.ServiceThread;
100 import com.android.server.SystemService;
101 import com.android.server.SystemServiceManager;
102 import com.android.server.Watchdog;
103 import com.android.server.am.ActivityStack.ActivityState;
104 import com.android.server.firewall.IntentFirewall;
105 import com.android.server.pm.Installer;
106 import com.android.server.pm.UserManagerService;
107 import com.android.server.statusbar.StatusBarManagerInternal;
108 import com.android.server.wm.AppTransition;
109 import com.android.server.wm.WindowManagerService;
110 import com.google.android.collect.Lists;
111 import com.google.android.collect.Maps;
112
113 import libcore.io.IoUtils;
114 import libcore.util.EmptyArray;
115
116 import org.xmlpull.v1.XmlPullParser;
117 import org.xmlpull.v1.XmlPullParserException;
118 import org.xmlpull.v1.XmlSerializer;
119
120 import android.app.Activity;
121 import android.app.ActivityManager;
122 import android.app.ActivityManager.RunningTaskInfo;
123 import android.app.ActivityManager.StackInfo;
124 import android.app.ActivityManagerInternal;
125 import android.app.ActivityManagerInternal.SleepToken;
126 import android.app.ActivityManagerNative;
127 import android.app.ActivityOptions;
128 import android.app.ActivityThread;
129 import android.app.AlertDialog;
130 import android.app.AppGlobals;
131 import android.app.ApplicationErrorReport;
132 import android.app.Dialog;
133 import android.app.IActivityController;
134 import android.app.IApplicationThread;
135 import android.app.IInstrumentationWatcher;
136 import android.app.INotificationManager;
137 import android.app.IProcessObserver;
138 import android.app.IServiceConnection;
139 import android.app.IStopUserCallback;
140 import android.app.IUidObserver;
141 import android.app.IUiAutomationConnection;
142 import android.app.IUserSwitchObserver;
143 import android.app.Instrumentation;
144 import android.app.Notification;
145 import android.app.NotificationManager;
146 import android.app.PendingIntent;
147 import android.app.backup.IBackupManager;
148 import android.app.admin.DevicePolicyManager;
149 import android.content.ActivityNotFoundException;
150 import android.content.BroadcastReceiver;
151 import android.content.ClipData;
152 import android.content.ComponentCallbacks2;
153 import android.content.ComponentName;
154 import android.content.ContentProvider;
155 import android.content.ContentResolver;
156 import android.content.Context;
157 import android.content.DialogInterface;
158 import android.content.IContentProvider;
159 import android.content.IIntentReceiver;
160 import android.content.IIntentSender;
161 import android.content.Intent;
162 import android.content.IntentFilter;
163 import android.content.IntentSender;
164 import android.content.pm.ActivityInfo;
165 import android.content.pm.ApplicationInfo;
166 import android.content.pm.ConfigurationInfo;
167 import android.content.pm.IPackageDataObserver;
168 import android.content.pm.IPackageManager;
169 import android.content.pm.InstrumentationInfo;
170 import android.content.pm.PackageInfo;
171 import android.content.pm.PackageManager;
172 import android.content.pm.ParceledListSlice;
173 import android.content.pm.UserInfo;
174 import android.content.pm.PackageManager.NameNotFoundException;
175 import android.content.pm.PathPermission;
176 import android.content.pm.ProviderInfo;
177 import android.content.pm.ResolveInfo;
178 import android.content.pm.ServiceInfo;
179 import android.content.res.CompatibilityInfo;
180 import android.content.res.Configuration;
181 import android.net.Proxy;
182 import android.net.ProxyInfo;
183 import android.net.Uri;
184 import android.os.Binder;
185 import android.os.Build;
186 import android.os.Bundle;
187 import android.os.Debug;
188 import android.os.DropBoxManager;
189 import android.os.Environment;
190 import android.os.FactoryTest;
191 import android.os.FileObserver;
192 import android.os.FileUtils;
193 import android.os.Handler;
194 import android.os.IBinder;
195 import android.os.IPermissionController;
196 import android.os.IProcessInfoService;
197 import android.os.IRemoteCallback;
198 import android.os.IUserManager;
199 import android.os.Looper;
200 import android.os.Message;
201 import android.os.Parcel;
202 import android.os.ParcelFileDescriptor;
203 import android.os.PowerManagerInternal;
204 import android.os.Process;
205 import android.os.RemoteCallbackList;
206 import android.os.RemoteException;
207 import android.os.SELinux;
208 import android.os.ServiceManager;
209 import android.os.StrictMode;
210 import android.os.SystemClock;
211 import android.os.SystemProperties;
212 import android.os.UpdateLock;
213 import android.os.UserHandle;
214 import android.os.UserManager;
215 import android.provider.Settings;
216 import android.text.format.DateUtils;
217 import android.text.format.Time;
218 import android.util.AtomicFile;
219 import android.util.EventLog;
220 import android.util.Log;
221 import android.util.Pair;
222 import android.util.PrintWriterPrinter;
223 import android.util.Slog;
224 import android.util.SparseArray;
225 import android.util.TimeUtils;
226 import android.util.Xml;
227 import android.view.Gravity;
228 import android.view.LayoutInflater;
229 import android.view.View;
230 import android.view.WindowManager;
231
232 import dalvik.system.VMRuntime;
233
234 import java.io.BufferedInputStream;
235 import java.io.BufferedOutputStream;
236 import java.io.DataInputStream;
237 import java.io.DataOutputStream;
238 import java.io.File;
239 import java.io.FileDescriptor;
240 import java.io.FileInputStream;
241 import java.io.FileNotFoundException;
242 import java.io.FileOutputStream;
243 import java.io.IOException;
244 import java.io.InputStreamReader;
245 import java.io.PrintWriter;
246 import java.io.StringWriter;
247 import java.lang.ref.WeakReference;
248 import java.nio.charset.StandardCharsets;
249 import java.util.ArrayList;
250 import java.util.Arrays;
251 import java.util.Collections;
252 import java.util.Comparator;
253 import java.util.HashMap;
254 import java.util.HashSet;
255 import java.util.Iterator;
256 import java.util.List;
257 import java.util.Locale;
258 import java.util.Map;
259 import java.util.Set;
260 import java.util.concurrent.atomic.AtomicBoolean;
261 import java.util.concurrent.atomic.AtomicLong;
262
263 public final class ActivityManagerService extends ActivityManagerNative
264         implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
265
266     // File that stores last updated system version and called preboot receivers
267     static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat";
268
269     private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
270     private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
271     private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
272     private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
273     private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
274     private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
275     private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
276     private static final String TAG_LOCKSCREEN = TAG + POSTFIX_LOCKSCREEN;
277     private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
278     private static final String TAG_LRU = TAG + POSTFIX_LRU;
279     private static final String TAG_MU = TAG + POSTFIX_MU;
280     private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
281     private static final String TAG_POWER = TAG + POSTFIX_POWER;
282     private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
283     private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
284     private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
285     private static final String TAG_PSS = TAG + POSTFIX_PSS;
286     private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
287     private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
288     private static final String TAG_STACK = TAG + POSTFIX_STACK;
289     private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
290     private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
291     private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
292     private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
293     private static final String TAG_VISIBLE_BEHIND = TAG + POSTFIX_VISIBLE_BEHIND;
294
295     /** Control over CPU and battery monitoring */
296     // write battery stats every 30 minutes.
297     static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
298     static final boolean MONITOR_CPU_USAGE = true;
299     // don't sample cpu less than every 5 seconds.
300     static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
301     // wait possibly forever for next cpu sample.
302     static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
303     static final boolean MONITOR_THREAD_CPU_USAGE = false;
304
305     // The flags that are set for all calls we make to the package manager.
306     static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
307
308     private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
309
310     static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
311
312     // Amount of time after a call to stopAppSwitches() during which we will
313     // prevent further untrusted switches from happening.
314     static final long APP_SWITCH_DELAY_TIME = 5*1000;
315
316     // How long we wait for a launched process to attach to the activity manager
317     // before we decide it's never going to come up for real.
318     static final int PROC_START_TIMEOUT = 10*1000;
319
320     // How long we wait for a launched process to attach to the activity manager
321     // before we decide it's never going to come up for real, when the process was
322     // started with a wrapper for instrumentation (such as Valgrind) because it
323     // could take much longer than usual.
324     static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
325
326     // How long to wait after going idle before forcing apps to GC.
327     static final int GC_TIMEOUT = 5*1000;
328
329     // The minimum amount of time between successive GC requests for a process.
330     static final int GC_MIN_INTERVAL = 60*1000;
331
332     // The minimum amount of time between successive PSS requests for a process.
333     static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
334
335     // The minimum amount of time between successive PSS requests for a process
336     // when the request is due to the memory state being lowered.
337     static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
338
339     // The rate at which we check for apps using excessive power -- 15 mins.
340     static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
341
342     // The minimum sample duration we will allow before deciding we have
343     // enough data on wake locks to start killing things.
344     static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
345
346     // The minimum sample duration we will allow before deciding we have
347     // enough data on CPU usage to start killing things.
348     static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
349
350     // How long we allow a receiver to run before giving up on it.
351     static final int BROADCAST_FG_TIMEOUT = 10*1000;
352     static final int BROADCAST_BG_TIMEOUT = 60*1000;
353
354     // How long we wait until we timeout on key dispatching.
355     static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
356
357     // How long we wait until we timeout on key dispatching during instrumentation.
358     static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
359
360     // Amount of time we wait for observers to handle a user switch before
361     // giving up on them and unfreezing the screen.
362     static final int USER_SWITCH_TIMEOUT = 2*1000;
363
364     // This is the amount of time an app needs to be running a foreground service before
365     // we will consider it to be doing interaction for usage stats.
366     static final int SERVICE_USAGE_INTERACTION_TIME = 30*60*1000;
367
368     // Maximum number of users we allow to be running at a time.
369     static final int MAX_RUNNING_USERS = 3;
370
371     // How long to wait in getAssistContextExtras for the activity and foreground services
372     // to respond with the result.
373     static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
374
375     // How long top wait when going through the modern assist (which doesn't need to block
376     // on getting this result before starting to launch its UI).
377     static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
378
379     // Maximum number of persisted Uri grants a package is allowed
380     static final int MAX_PERSISTED_URI_GRANTS = 128;
381
382     static final int MY_PID = Process.myPid();
383
384     static final String[] EMPTY_STRING_ARRAY = new String[0];
385
386     // How many bytes to write into the dropbox log before truncating
387     static final int DROPBOX_MAX_SIZE = 256 * 1024;
388
389     // Access modes for handleIncomingUser.
390     static final int ALLOW_NON_FULL = 0;
391     static final int ALLOW_NON_FULL_IN_PROFILE = 1;
392     static final int ALLOW_FULL_ONLY = 2;
393
394     static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000;
395
396     // Delay in notifying task stack change listeners (in millis)
397     static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 1000;
398
399     // Necessary ApplicationInfo flags to mark an app as persistent
400     private static final int PERSISTENT_MASK =
401             ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
402
403     /** All system services */
404     SystemServiceManager mSystemServiceManager;
405
406     private Installer mInstaller;
407
408     /** Run all ActivityStacks through this */
409     ActivityStackSupervisor mStackSupervisor;
410
411     /** Task stack change listeners. */
412     private RemoteCallbackList<ITaskStackListener> mTaskStackListeners =
413             new RemoteCallbackList<ITaskStackListener>();
414
415     public IntentFirewall mIntentFirewall;
416
417     // Whether we should show our dialogs (ANR, crash, etc) or just perform their
418     // default actuion automatically.  Important for devices without direct input
419     // devices.
420     private boolean mShowDialogs = true;
421
422     BroadcastQueue mFgBroadcastQueue;
423     BroadcastQueue mBgBroadcastQueue;
424     // Convenient for easy iteration over the queues. Foreground is first
425     // so that dispatch of foreground broadcasts gets precedence.
426     final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
427
428     BroadcastQueue broadcastQueueForIntent(Intent intent) {
429         final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
430         if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
431                 "Broadcast intent " + intent + " on "
432                 + (isFg ? "foreground" : "background") + " queue");
433         return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
434     }
435
436     /**
437      * Activity we have told the window manager to have key focus.
438      */
439     ActivityRecord mFocusedActivity = null;
440
441     /**
442      * User id of the last activity mFocusedActivity was set to.
443      */
444     private int mLastFocusedUserId;
445
446     /**
447      * If non-null, we are tracking the time the user spends in the currently focused app.
448      */
449     private AppTimeTracker mCurAppTimeTracker;
450
451     /**
452      * List of intents that were used to start the most recent tasks.
453      */
454     private final RecentTasks mRecentTasks;
455
456     /**
457      * For addAppTask: cached of the last activity component that was added.
458      */
459     ComponentName mLastAddedTaskComponent;
460
461     /**
462      * For addAppTask: cached of the last activity uid that was added.
463      */
464     int mLastAddedTaskUid;
465
466     /**
467      * For addAppTask: cached of the last ActivityInfo that was added.
468      */
469     ActivityInfo mLastAddedTaskActivity;
470
471     /**
472      * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId.
473      */
474     SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
475
476     /**
477      * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
478      */
479     String mDeviceOwnerName;
480
481     public class PendingAssistExtras extends Binder implements Runnable {
482         public final ActivityRecord activity;
483         public final Bundle extras;
484         public final Intent intent;
485         public final String hint;
486         public final IResultReceiver receiver;
487         public final int userHandle;
488         public boolean haveResult = false;
489         public Bundle result = null;
490         public AssistStructure structure = null;
491         public AssistContent content = null;
492         public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
493                 String _hint, IResultReceiver _receiver, int _userHandle) {
494             activity = _activity;
495             extras = _extras;
496             intent = _intent;
497             hint = _hint;
498             receiver = _receiver;
499             userHandle = _userHandle;
500         }
501         @Override
502         public void run() {
503             Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
504             synchronized (this) {
505                 haveResult = true;
506                 notifyAll();
507             }
508             pendingAssistExtrasTimedOut(this);
509         }
510     }
511
512     final ArrayList<PendingAssistExtras> mPendingAssistExtras
513             = new ArrayList<PendingAssistExtras>();
514
515     /**
516      * Process management.
517      */
518     final ProcessList mProcessList = new ProcessList();
519
520     /**
521      * All of the applications we currently have running organized by name.
522      * The keys are strings of the application package name (as
523      * returned by the package manager), and the keys are ApplicationRecord
524      * objects.
525      */
526     final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
527
528     /**
529      * Tracking long-term execution of processes to look for abuse and other
530      * bad app behavior.
531      */
532     final ProcessStatsService mProcessStats;
533
534     /**
535      * The currently running isolated processes.
536      */
537     final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
538
539     /**
540      * Counter for assigning isolated process uids, to avoid frequently reusing the
541      * same ones.
542      */
543     int mNextIsolatedProcessUid = 0;
544
545     /**
546      * The currently running heavy-weight process, if any.
547      */
548     ProcessRecord mHeavyWeightProcess = null;
549
550     /**
551      * The last time that various processes have crashed.
552      */
553     final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
554
555     /**
556      * Information about a process that is currently marked as bad.
557      */
558     static final class BadProcessInfo {
559         BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
560             this.time = time;
561             this.shortMsg = shortMsg;
562             this.longMsg = longMsg;
563             this.stack = stack;
564         }
565
566         final long time;
567         final String shortMsg;
568         final String longMsg;
569         final String stack;
570     }
571
572     /**
573      * Set of applications that we consider to be bad, and will reject
574      * incoming broadcasts from (which the user has no control over).
575      * Processes are added to this set when they have crashed twice within
576      * a minimum amount of time; they are removed from it when they are
577      * later restarted (hopefully due to some user action).  The value is the
578      * time it was added to the list.
579      */
580     final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
581
582     /**
583      * All of the processes we currently have running organized by pid.
584      * The keys are the pid running the application.
585      *
586      * <p>NOTE: This object is protected by its own lock, NOT the global
587      * activity manager lock!
588      */
589     final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
590
591     /**
592      * All of the processes that have been forced to be foreground.  The key
593      * is the pid of the caller who requested it (we hold a death
594      * link on it).
595      */
596     abstract class ForegroundToken implements IBinder.DeathRecipient {
597         int pid;
598         IBinder token;
599     }
600     final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
601
602     /**
603      * List of records for processes that someone had tried to start before the
604      * system was ready.  We don't start them at that point, but ensure they
605      * are started by the time booting is complete.
606      */
607     final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
608
609     /**
610      * List of persistent applications that are in the process
611      * of being started.
612      */
613     final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
614
615     /**
616      * Processes that are being forcibly torn down.
617      */
618     final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
619
620     /**
621      * List of running applications, sorted by recent usage.
622      * The first entry in the list is the least recently used.
623      */
624     final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
625
626     /**
627      * Where in mLruProcesses that the processes hosting activities start.
628      */
629     int mLruProcessActivityStart = 0;
630
631     /**
632      * Where in mLruProcesses that the processes hosting services start.
633      * This is after (lower index) than mLruProcessesActivityStart.
634      */
635     int mLruProcessServiceStart = 0;
636
637     /**
638      * List of processes that should gc as soon as things are idle.
639      */
640     final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
641
642     /**
643      * Processes we want to collect PSS data from.
644      */
645     final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
646
647     /**
648      * Last time we requested PSS data of all processes.
649      */
650     long mLastFullPssTime = SystemClock.uptimeMillis();
651
652     /**
653      * If set, the next time we collect PSS data we should do a full collection
654      * with data from native processes and the kernel.
655      */
656     boolean mFullPssPending = false;
657
658     /**
659      * This is the process holding what we currently consider to be
660      * the "home" activity.
661      */
662     ProcessRecord mHomeProcess;
663
664     /**
665      * This is the process holding the activity the user last visited that
666      * is in a different process from the one they are currently in.
667      */
668     ProcessRecord mPreviousProcess;
669
670     /**
671      * The time at which the previous process was last visible.
672      */
673     long mPreviousProcessVisibleTime;
674
675     /**
676      * Track all uids that have actively running processes.
677      */
678     final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
679
680     /**
681      * Which users have been started, so are allowed to run code.
682      */
683     final SparseArray<UserState> mStartedUsers = new SparseArray<>();
684
685     /**
686      * LRU list of history of current users.  Most recently current is at the end.
687      */
688     final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
689
690     /**
691      * Constant array of the users that are currently started.
692      */
693     int[] mStartedUserArray = new int[] { 0 };
694
695     /**
696      * Registered observers of the user switching mechanics.
697      */
698     final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
699             = new RemoteCallbackList<IUserSwitchObserver>();
700
701     /**
702      * Currently active user switch.
703      */
704     Object mCurUserSwitchCallback;
705
706     /**
707      * Packages that the user has asked to have run in screen size
708      * compatibility mode instead of filling the screen.
709      */
710     final CompatModePackages mCompatModePackages;
711
712     /**
713      * Set of IntentSenderRecord objects that are currently active.
714      */
715     final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
716             = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
717
718     /**
719      * Fingerprints (hashCode()) of stack traces that we've
720      * already logged DropBox entries for.  Guarded by itself.  If
721      * something (rogue user app) forces this over
722      * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
723      */
724     private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
725     private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
726
727     /**
728      * Strict Mode background batched logging state.
729      *
730      * The string buffer is guarded by itself, and its lock is also
731      * used to determine if another batched write is already
732      * in-flight.
733      */
734     private final StringBuilder mStrictModeBuffer = new StringBuilder();
735
736     /**
737      * Keeps track of all IIntentReceivers that have been registered for broadcasts.
738      * Hash keys are the receiver IBinder, hash value is a ReceiverList.
739      */
740     final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
741
742     /**
743      * Resolver for broadcast intents to registered receivers.
744      * Holds BroadcastFilter (subclass of IntentFilter).
745      */
746     final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
747             = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
748         @Override
749         protected boolean allowFilterResult(
750                 BroadcastFilter filter, List<BroadcastFilter> dest) {
751             IBinder target = filter.receiverList.receiver.asBinder();
752             for (int i = dest.size() - 1; i >= 0; i--) {
753                 if (dest.get(i).receiverList.receiver.asBinder() == target) {
754                     return false;
755                 }
756             }
757             return true;
758         }
759
760         @Override
761         protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
762             if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
763                     || userId == filter.owningUserId) {
764                 return super.newResult(filter, match, userId);
765             }
766             return null;
767         }
768
769         @Override
770         protected BroadcastFilter[] newArray(int size) {
771             return new BroadcastFilter[size];
772         }
773
774         @Override
775         protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
776             return packageName.equals(filter.packageName);
777         }
778     };
779
780     /**
781      * State of all active sticky broadcasts per user.  Keys are the action of the
782      * sticky Intent, values are an ArrayList of all broadcasted intents with
783      * that action (which should usually be one).  The SparseArray is keyed
784      * by the user ID the sticky is for, and can include UserHandle.USER_ALL
785      * for stickies that are sent to all users.
786      */
787     final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
788             new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
789
790     final ActiveServices mServices;
791
792     final static class Association {
793         final int mSourceUid;
794         final String mSourceProcess;
795         final int mTargetUid;
796         final ComponentName mTargetComponent;
797         final String mTargetProcess;
798
799         int mCount;
800         long mTime;
801
802         int mNesting;
803         long mStartTime;
804
805         Association(int sourceUid, String sourceProcess, int targetUid,
806                 ComponentName targetComponent, String targetProcess) {
807             mSourceUid = sourceUid;
808             mSourceProcess = sourceProcess;
809             mTargetUid = targetUid;
810             mTargetComponent = targetComponent;
811             mTargetProcess = targetProcess;
812         }
813     }
814
815     /**
816      * When service association tracking is enabled, this is all of the associations we
817      * have seen.  Mapping is target uid -> target component -> source uid -> source process name
818      * -> association data.
819      */
820     final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
821             mAssociations = new SparseArray<>();
822     boolean mTrackingAssociations;
823
824     /**
825      * Backup/restore process management
826      */
827     String mBackupAppName = null;
828     BackupRecord mBackupTarget = null;
829
830     final ProviderMap mProviderMap;
831
832     /**
833      * List of content providers who have clients waiting for them.  The
834      * application is currently being launched and the provider will be
835      * removed from this list once it is published.
836      */
837     final ArrayList<ContentProviderRecord> mLaunchingProviders
838             = new ArrayList<ContentProviderRecord>();
839
840     /**
841      * File storing persisted {@link #mGrantedUriPermissions}.
842      */
843     private final AtomicFile mGrantFile;
844
845     /** XML constants used in {@link #mGrantFile} */
846     private static final String TAG_URI_GRANTS = "uri-grants";
847     private static final String TAG_URI_GRANT = "uri-grant";
848     private static final String ATTR_USER_HANDLE = "userHandle";
849     private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
850     private static final String ATTR_TARGET_USER_ID = "targetUserId";
851     private static final String ATTR_SOURCE_PKG = "sourcePkg";
852     private static final String ATTR_TARGET_PKG = "targetPkg";
853     private static final String ATTR_URI = "uri";
854     private static final String ATTR_MODE_FLAGS = "modeFlags";
855     private static final String ATTR_CREATED_TIME = "createdTime";
856     private static final String ATTR_PREFIX = "prefix";
857
858     /**
859      * Global set of specific {@link Uri} permissions that have been granted.
860      * This optimized lookup structure maps from {@link UriPermission#targetUid}
861      * to {@link UriPermission#uri} to {@link UriPermission}.
862      */
863     @GuardedBy("this")
864     private final SparseArray<ArrayMap<GrantUri, UriPermission>>
865             mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
866
867     public static class GrantUri {
868         public final int sourceUserId;
869         public final Uri uri;
870         public boolean prefix;
871
872         public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
873             this.sourceUserId = sourceUserId;
874             this.uri = uri;
875             this.prefix = prefix;
876         }
877
878         @Override
879         public int hashCode() {
880             int hashCode = 1;
881             hashCode = 31 * hashCode + sourceUserId;
882             hashCode = 31 * hashCode + uri.hashCode();
883             hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
884             return hashCode;
885         }
886
887         @Override
888         public boolean equals(Object o) {
889             if (o instanceof GrantUri) {
890                 GrantUri other = (GrantUri) o;
891                 return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
892                         && prefix == other.prefix;
893             }
894             return false;
895         }
896
897         @Override
898         public String toString() {
899             String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
900             if (prefix) result += " [prefix]";
901             return result;
902         }
903
904         public String toSafeString() {
905             String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
906             if (prefix) result += " [prefix]";
907             return result;
908         }
909
910         public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
911             return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
912                     ContentProvider.getUriWithoutUserId(uri), false);
913         }
914     }
915
916     CoreSettingsObserver mCoreSettingsObserver;
917
918     /**
919      * Thread-local storage used to carry caller permissions over through
920      * indirect content-provider access.
921      */
922     private class Identity {
923         public final IBinder token;
924         public final int pid;
925         public final int uid;
926
927         Identity(IBinder _token, int _pid, int _uid) {
928             token = _token;
929             pid = _pid;
930             uid = _uid;
931         }
932     }
933
934     private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
935
936     /**
937      * All information we have collected about the runtime performance of
938      * any user id that can impact battery performance.
939      */
940     final BatteryStatsService mBatteryStatsService;
941
942     /**
943      * Information about component usage
944      */
945     UsageStatsManagerInternal mUsageStatsService;
946
947     /**
948      * Access to DeviceIdleController service.
949      */
950     DeviceIdleController.LocalService mLocalDeviceIdleController;
951
952     /**
953      * Information about and control over application operations
954      */
955     final AppOpsService mAppOpsService;
956
957     /**
958      * Save recent tasks information across reboots.
959      */
960     final TaskPersister mTaskPersister;
961
962     /**
963      * Current configuration information.  HistoryRecord objects are given
964      * a reference to this object to indicate which configuration they are
965      * currently running in, so this object must be kept immutable.
966      */
967     Configuration mConfiguration = new Configuration();
968
969     /**
970      * Current sequencing integer of the configuration, for skipping old
971      * configurations.
972      */
973     int mConfigurationSeq = 0;
974
975     /**
976      * Hardware-reported OpenGLES version.
977      */
978     final int GL_ES_VERSION;
979
980     /**
981      * List of initialization arguments to pass to all processes when binding applications to them.
982      * For example, references to the commonly used services.
983      */
984     HashMap<String, IBinder> mAppBindArgs;
985
986     /**
987      * Temporary to avoid allocations.  Protected by main lock.
988      */
989     final StringBuilder mStringBuilder = new StringBuilder(256);
990
991     /**
992      * Used to control how we initialize the service.
993      */
994     ComponentName mTopComponent;
995     String mTopAction = Intent.ACTION_MAIN;
996     String mTopData;
997     boolean mProcessesReady = false;
998     boolean mSystemReady = false;
999     boolean mBooting = false;
1000     boolean mCallFinishBooting = false;
1001     boolean mBootAnimationComplete = false;
1002     boolean mWaitingUpdate = false;
1003     boolean mDidUpdate = false;
1004     boolean mOnBattery = false;
1005     boolean mLaunchWarningShown = false;
1006
1007     Context mContext;
1008
1009     int mFactoryTest;
1010
1011     boolean mCheckedForSetup;
1012
1013     /**
1014      * The time at which we will allow normal application switches again,
1015      * after a call to {@link #stopAppSwitches()}.
1016      */
1017     long mAppSwitchesAllowedTime;
1018
1019     /**
1020      * This is set to true after the first switch after mAppSwitchesAllowedTime
1021      * is set; any switches after that will clear the time.
1022      */
1023     boolean mDidAppSwitch;
1024
1025     /**
1026      * Last time (in realtime) at which we checked for power usage.
1027      */
1028     long mLastPowerCheckRealtime;
1029
1030     /**
1031      * Last time (in uptime) at which we checked for power usage.
1032      */
1033     long mLastPowerCheckUptime;
1034
1035     /**
1036      * Set while we are wanting to sleep, to prevent any
1037      * activities from being started/resumed.
1038      */
1039     private boolean mSleeping = false;
1040
1041     /**
1042      * The process state used for processes that are running the top activities.
1043      * This changes between TOP and TOP_SLEEPING to following mSleeping.
1044      */
1045     int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1046
1047     /**
1048      * Set while we are running a voice interaction.  This overrides
1049      * sleeping while it is active.
1050      */
1051     private IVoiceInteractionSession mRunningVoice;
1052
1053     /**
1054      * For some direct access we need to power manager.
1055      */
1056     PowerManagerInternal mLocalPowerManager;
1057
1058     /**
1059      * We want to hold a wake lock while running a voice interaction session, since
1060      * this may happen with the screen off and we need to keep the CPU running to
1061      * be able to continue to interact with the user.
1062      */
1063     PowerManager.WakeLock mVoiceWakeLock;
1064
1065     /**
1066      * State of external calls telling us if the device is awake or asleep.
1067      */
1068     private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1069
1070     /**
1071      * A list of tokens that cause the top activity to be put to sleep.
1072      * They are used by components that may hide and block interaction with underlying
1073      * activities.
1074      */
1075     final ArrayList<SleepToken> mSleepTokens = new ArrayList<SleepToken>();
1076
1077     static final int LOCK_SCREEN_HIDDEN = 0;
1078     static final int LOCK_SCREEN_LEAVING = 1;
1079     static final int LOCK_SCREEN_SHOWN = 2;
1080     /**
1081      * State of external call telling us if the lock screen is shown.
1082      */
1083     int mLockScreenShown = LOCK_SCREEN_HIDDEN;
1084
1085     /**
1086      * Set if we are shutting down the system, similar to sleeping.
1087      */
1088     boolean mShuttingDown = false;
1089
1090     /**
1091      * Current sequence id for oom_adj computation traversal.
1092      */
1093     int mAdjSeq = 0;
1094
1095     /**
1096      * Current sequence id for process LRU updating.
1097      */
1098     int mLruSeq = 0;
1099
1100     /**
1101      * Keep track of the non-cached/empty process we last found, to help
1102      * determine how to distribute cached/empty processes next time.
1103      */
1104     int mNumNonCachedProcs = 0;
1105
1106     /**
1107      * Keep track of the number of cached hidden procs, to balance oom adj
1108      * distribution between those and empty procs.
1109      */
1110     int mNumCachedHiddenProcs = 0;
1111
1112     /**
1113      * Keep track of the number of service processes we last found, to
1114      * determine on the next iteration which should be B services.
1115      */
1116     int mNumServiceProcs = 0;
1117     int mNewNumAServiceProcs = 0;
1118     int mNewNumServiceProcs = 0;
1119
1120     /**
1121      * Allow the current computed overall memory level of the system to go down?
1122      * This is set to false when we are killing processes for reasons other than
1123      * memory management, so that the now smaller process list will not be taken as
1124      * an indication that memory is tighter.
1125      */
1126     boolean mAllowLowerMemLevel = false;
1127
1128     /**
1129      * The last computed memory level, for holding when we are in a state that
1130      * processes are going away for other reasons.
1131      */
1132     int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1133
1134     /**
1135      * The last total number of process we have, to determine if changes actually look
1136      * like a shrinking number of process due to lower RAM.
1137      */
1138     int mLastNumProcesses;
1139
1140     /**
1141      * The uptime of the last time we performed idle maintenance.
1142      */
1143     long mLastIdleTime = SystemClock.uptimeMillis();
1144
1145     /**
1146      * Total time spent with RAM that has been added in the past since the last idle time.
1147      */
1148     long mLowRamTimeSinceLastIdle = 0;
1149
1150     /**
1151      * If RAM is currently low, when that horrible situation started.
1152      */
1153     long mLowRamStartTime = 0;
1154
1155     /**
1156      * For reporting to battery stats the current top application.
1157      */
1158     private String mCurResumedPackage = null;
1159     private int mCurResumedUid = -1;
1160
1161     /**
1162      * For reporting to battery stats the apps currently running foreground
1163      * service.  The ProcessMap is package/uid tuples; each of these contain
1164      * an array of the currently foreground processes.
1165      */
1166     final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1167             = new ProcessMap<ArrayList<ProcessRecord>>();
1168
1169     /**
1170      * This is set if we had to do a delayed dexopt of an app before launching
1171      * it, to increase the ANR timeouts in that case.
1172      */
1173     boolean mDidDexOpt;
1174
1175     /**
1176      * Set if the systemServer made a call to enterSafeMode.
1177      */
1178     boolean mSafeMode;
1179
1180     /**
1181      * If true, we are running under a test environment so will sample PSS from processes
1182      * much more rapidly to try to collect better data when the tests are rapidly
1183      * running through apps.
1184      */
1185     boolean mTestPssMode = false;
1186
1187     String mDebugApp = null;
1188     boolean mWaitForDebugger = false;
1189     boolean mDebugTransient = false;
1190     String mOrigDebugApp = null;
1191     boolean mOrigWaitForDebugger = false;
1192     boolean mAlwaysFinishActivities = false;
1193     IActivityController mController = null;
1194     String mProfileApp = null;
1195     ProcessRecord mProfileProc = null;
1196     String mProfileFile;
1197     ParcelFileDescriptor mProfileFd;
1198     int mSamplingInterval = 0;
1199     boolean mAutoStopProfiler = false;
1200     int mProfileType = 0;
1201     String mOpenGlTraceApp = null;
1202     final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1203     String mMemWatchDumpProcName;
1204     String mMemWatchDumpFile;
1205     int mMemWatchDumpPid;
1206     int mMemWatchDumpUid;
1207
1208     final long[] mTmpLong = new long[1];
1209
1210     static final class ProcessChangeItem {
1211         static final int CHANGE_ACTIVITIES = 1<<0;
1212         static final int CHANGE_PROCESS_STATE = 1<<1;
1213         int changes;
1214         int uid;
1215         int pid;
1216         int processState;
1217         boolean foregroundActivities;
1218     }
1219
1220     final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1221     ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1222
1223     final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1224     final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1225
1226     final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1227     UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1228
1229     final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1230     final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1231
1232     /**
1233      * Runtime CPU use collection thread.  This object's lock is used to
1234      * perform synchronization with the thread (notifying it to run).
1235      */
1236     final Thread mProcessCpuThread;
1237
1238     /**
1239      * Used to collect per-process CPU use for ANRs, battery stats, etc.
1240      * Must acquire this object's lock when accessing it.
1241      * NOTE: this lock will be held while doing long operations (trawling
1242      * through all processes in /proc), so it should never be acquired by
1243      * any critical paths such as when holding the main activity manager lock.
1244      */
1245     final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1246             MONITOR_THREAD_CPU_USAGE);
1247     final AtomicLong mLastCpuTime = new AtomicLong(0);
1248     final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1249
1250     long mLastWriteTime = 0;
1251
1252     /**
1253      * Used to retain an update lock when the foreground activity is in
1254      * immersive mode.
1255      */
1256     final UpdateLock mUpdateLock = new UpdateLock("immersive");
1257
1258     /**
1259      * Set to true after the system has finished booting.
1260      */
1261     boolean mBooted = false;
1262
1263     int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1264     int mProcessLimitOverride = -1;
1265
1266     WindowManagerService mWindowManager;
1267
1268     final ActivityThread mSystemThread;
1269
1270     // Holds the current foreground user's id
1271     int mCurrentUserId = 0;
1272     // Holds the target user's id during a user switch
1273     int mTargetUserId = UserHandle.USER_NULL;
1274     // If there are multiple profiles for the current user, their ids are here
1275     // Currently only the primary user can have managed profiles
1276     int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1277
1278     /**
1279      * Mapping from each known user ID to the profile group ID it is associated with.
1280      */
1281     SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray();
1282
1283     private UserManagerService mUserManager;
1284
1285     private final class AppDeathRecipient implements IBinder.DeathRecipient {
1286         final ProcessRecord mApp;
1287         final int mPid;
1288         final IApplicationThread mAppThread;
1289
1290         AppDeathRecipient(ProcessRecord app, int pid,
1291                 IApplicationThread thread) {
1292             if (DEBUG_ALL) Slog.v(
1293                 TAG, "New death recipient " + this
1294                 + " for thread " + thread.asBinder());
1295             mApp = app;
1296             mPid = pid;
1297             mAppThread = thread;
1298         }
1299
1300         @Override
1301         public void binderDied() {
1302             if (DEBUG_ALL) Slog.v(
1303                 TAG, "Death received in " + this
1304                 + " for thread " + mAppThread.asBinder());
1305             synchronized(ActivityManagerService.this) {
1306                 appDiedLocked(mApp, mPid, mAppThread, true);
1307             }
1308         }
1309     }
1310
1311     static final int SHOW_ERROR_MSG = 1;
1312     static final int SHOW_NOT_RESPONDING_MSG = 2;
1313     static final int SHOW_FACTORY_ERROR_MSG = 3;
1314     static final int UPDATE_CONFIGURATION_MSG = 4;
1315     static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1316     static final int WAIT_FOR_DEBUGGER_MSG = 6;
1317     static final int SERVICE_TIMEOUT_MSG = 12;
1318     static final int UPDATE_TIME_ZONE = 13;
1319     static final int SHOW_UID_ERROR_MSG = 14;
1320     static final int SHOW_FINGERPRINT_ERROR_MSG = 15;
1321     static final int PROC_START_TIMEOUT_MSG = 20;
1322     static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1323     static final int KILL_APPLICATION_MSG = 22;
1324     static final int FINALIZE_PENDING_INTENT_MSG = 23;
1325     static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1326     static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1327     static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1328     static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1329     static final int CLEAR_DNS_CACHE_MSG = 28;
1330     static final int UPDATE_HTTP_PROXY_MSG = 29;
1331     static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1332     static final int DISPATCH_PROCESSES_CHANGED = 31;
1333     static final int DISPATCH_PROCESS_DIED = 32;
1334     static final int REPORT_MEM_USAGE_MSG = 33;
1335     static final int REPORT_USER_SWITCH_MSG = 34;
1336     static final int CONTINUE_USER_SWITCH_MSG = 35;
1337     static final int USER_SWITCH_TIMEOUT_MSG = 36;
1338     static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1339     static final int PERSIST_URI_GRANTS_MSG = 38;
1340     static final int REQUEST_ALL_PSS_MSG = 39;
1341     static final int START_PROFILES_MSG = 40;
1342     static final int UPDATE_TIME = 41;
1343     static final int SYSTEM_USER_START_MSG = 42;
1344     static final int SYSTEM_USER_CURRENT_MSG = 43;
1345     static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1346     static final int FINISH_BOOTING_MSG = 45;
1347     static final int START_USER_SWITCH_MSG = 46;
1348     static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1349     static final int DISMISS_DIALOG_MSG = 48;
1350     static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49;
1351     static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 50;
1352     static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 51;
1353     static final int DELETE_DUMPHEAP_MSG = 52;
1354     static final int FOREGROUND_PROFILE_CHANGED_MSG = 53;
1355     static final int DISPATCH_UIDS_CHANGED_MSG = 54;
1356     static final int REPORT_TIME_TRACKER_MSG = 55;
1357     static final int REPORT_USER_SWITCH_COMPLETE_MSG = 56;
1358     static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 57;
1359
1360     static final int FIRST_ACTIVITY_STACK_MSG = 100;
1361     static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1362     static final int FIRST_COMPAT_MODE_MSG = 300;
1363     static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1364
1365     CompatModeDialog mCompatModeDialog;
1366     long mLastMemUsageReportTime = 0;
1367
1368     /**
1369      * Flag whether the current user is a "monkey", i.e. whether
1370      * the UI is driven by a UI automation tool.
1371      */
1372     private boolean mUserIsMonkey;
1373
1374     /** Flag whether the device has a Recents UI */
1375     boolean mHasRecents;
1376
1377     /** The dimensions of the thumbnails in the Recents UI. */
1378     int mThumbnailWidth;
1379     int mThumbnailHeight;
1380
1381     final ServiceThread mHandlerThread;
1382     final MainHandler mHandler;
1383     final UiHandler mUiHandler;
1384
1385     final class UiHandler extends Handler {
1386         public UiHandler() {
1387             super(com.android.server.UiThread.get().getLooper(), null, true);
1388         }
1389
1390         @Override
1391         public void handleMessage(Message msg) {
1392             switch (msg.what) {
1393             case SHOW_ERROR_MSG: {
1394                 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1395                 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1396                         Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1397                 synchronized (ActivityManagerService.this) {
1398                     ProcessRecord proc = (ProcessRecord)data.get("app");
1399                     AppErrorResult res = (AppErrorResult) data.get("result");
1400                     if (proc != null && proc.crashDialog != null) {
1401                         Slog.e(TAG, "App already has crash dialog: " + proc);
1402                         if (res != null) {
1403                             res.set(0);
1404                         }
1405                         return;
1406                     }
1407                     boolean isBackground = (UserHandle.getAppId(proc.uid)
1408                             >= Process.FIRST_APPLICATION_UID
1409                             && proc.pid != MY_PID);
1410                     for (int userId : mCurrentProfileIds) {
1411                         isBackground &= (proc.userId != userId);
1412                     }
1413                     if (isBackground && !showBackground) {
1414                         Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1415                         if (res != null) {
1416                             res.set(0);
1417                         }
1418                         return;
1419                     }
1420                     if (mShowDialogs && !mSleeping && !mShuttingDown) {
1421                         Dialog d = new AppErrorDialog(mContext,
1422                                 ActivityManagerService.this, res, proc);
1423                         d.show();
1424                         proc.crashDialog = d;
1425                     } else {
1426                         // The device is asleep, so just pretend that the user
1427                         // saw a crash dialog and hit "force quit".
1428                         if (res != null) {
1429                             res.set(0);
1430                         }
1431                     }
1432                 }
1433
1434                 ensureBootCompleted();
1435             } break;
1436             case SHOW_NOT_RESPONDING_MSG: {
1437                 synchronized (ActivityManagerService.this) {
1438                     HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1439                     ProcessRecord proc = (ProcessRecord)data.get("app");
1440                     if (proc != null && proc.anrDialog != null) {
1441                         Slog.e(TAG, "App already has anr dialog: " + proc);
1442                         return;
1443                     }
1444
1445                     Intent intent = new Intent("android.intent.action.ANR");
1446                     if (!mProcessesReady) {
1447                         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1448                                 | Intent.FLAG_RECEIVER_FOREGROUND);
1449                     }
1450                     broadcastIntentLocked(null, null, intent,
1451                             null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1452                             null, false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1453
1454                     if (mShowDialogs) {
1455                         Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1456                                 mContext, proc, (ActivityRecord)data.get("activity"),
1457                                 msg.arg1 != 0);
1458                         d.show();
1459                         proc.anrDialog = d;
1460                     } else {
1461                         // Just kill the app if there is no dialog to be shown.
1462                         killAppAtUsersRequest(proc, null);
1463                     }
1464                 }
1465
1466                 ensureBootCompleted();
1467             } break;
1468             case SHOW_STRICT_MODE_VIOLATION_MSG: {
1469                 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1470                 synchronized (ActivityManagerService.this) {
1471                     ProcessRecord proc = (ProcessRecord) data.get("app");
1472                     if (proc == null) {
1473                         Slog.e(TAG, "App not found when showing strict mode dialog.");
1474                         break;
1475                     }
1476                     if (proc.crashDialog != null) {
1477                         Slog.e(TAG, "App already has strict mode dialog: " + proc);
1478                         return;
1479                     }
1480                     AppErrorResult res = (AppErrorResult) data.get("result");
1481                     if (mShowDialogs && !mSleeping && !mShuttingDown) {
1482                         Dialog d = new StrictModeViolationDialog(mContext,
1483                                 ActivityManagerService.this, res, proc);
1484                         d.show();
1485                         proc.crashDialog = d;
1486                     } else {
1487                         // The device is asleep, so just pretend that the user
1488                         // saw a crash dialog and hit "force quit".
1489                         res.set(0);
1490                     }
1491                 }
1492                 ensureBootCompleted();
1493             } break;
1494             case SHOW_FACTORY_ERROR_MSG: {
1495                 Dialog d = new FactoryErrorDialog(
1496                     mContext, msg.getData().getCharSequence("msg"));
1497                 d.show();
1498                 ensureBootCompleted();
1499             } break;
1500             case WAIT_FOR_DEBUGGER_MSG: {
1501                 synchronized (ActivityManagerService.this) {
1502                     ProcessRecord app = (ProcessRecord)msg.obj;
1503                     if (msg.arg1 != 0) {
1504                         if (!app.waitedForDebugger) {
1505                             Dialog d = new AppWaitingForDebuggerDialog(
1506                                     ActivityManagerService.this,
1507                                     mContext, app);
1508                             app.waitDialog = d;
1509                             app.waitedForDebugger = true;
1510                             d.show();
1511                         }
1512                     } else {
1513                         if (app.waitDialog != null) {
1514                             app.waitDialog.dismiss();
1515                             app.waitDialog = null;
1516                         }
1517                     }
1518                 }
1519             } break;
1520             case SHOW_UID_ERROR_MSG: {
1521                 if (mShowDialogs) {
1522                     AlertDialog d = new BaseErrorDialog(mContext);
1523                     d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1524                     d.setCancelable(false);
1525                     d.setTitle(mContext.getText(R.string.android_system_label));
1526                     d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1527                     d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1528                             obtainMessage(DISMISS_DIALOG_MSG, d));
1529                     d.show();
1530                 }
1531             } break;
1532             case SHOW_FINGERPRINT_ERROR_MSG: {
1533                 if (mShowDialogs) {
1534                     AlertDialog d = new BaseErrorDialog(mContext);
1535                     d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1536                     d.setCancelable(false);
1537                     d.setTitle(mContext.getText(R.string.android_system_label));
1538                     d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1539                     d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1540                             obtainMessage(DISMISS_DIALOG_MSG, d));
1541                     d.show();
1542                 }
1543             } break;
1544             case SHOW_COMPAT_MODE_DIALOG_MSG: {
1545                 synchronized (ActivityManagerService.this) {
1546                     ActivityRecord ar = (ActivityRecord) msg.obj;
1547                     if (mCompatModeDialog != null) {
1548                         if (mCompatModeDialog.mAppInfo.packageName.equals(
1549                                 ar.info.applicationInfo.packageName)) {
1550                             return;
1551                         }
1552                         mCompatModeDialog.dismiss();
1553                         mCompatModeDialog = null;
1554                     }
1555                     if (ar != null && false) {
1556                         if (mCompatModePackages.getPackageAskCompatModeLocked(
1557                                 ar.packageName)) {
1558                             int mode = mCompatModePackages.computeCompatModeLocked(
1559                                     ar.info.applicationInfo);
1560                             if (mode == ActivityManager.COMPAT_MODE_DISABLED
1561                                     || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1562                                 mCompatModeDialog = new CompatModeDialog(
1563                                         ActivityManagerService.this, mContext,
1564                                         ar.info.applicationInfo);
1565                                 mCompatModeDialog.show();
1566                             }
1567                         }
1568                     }
1569                 }
1570                 break;
1571             }
1572             case START_USER_SWITCH_MSG: {
1573                 showUserSwitchDialog(msg.arg1, (String) msg.obj);
1574                 break;
1575             }
1576             case DISMISS_DIALOG_MSG: {
1577                 final Dialog d = (Dialog) msg.obj;
1578                 d.dismiss();
1579                 break;
1580             }
1581             case DISPATCH_PROCESSES_CHANGED: {
1582                 dispatchProcessesChanged();
1583                 break;
1584             }
1585             case DISPATCH_PROCESS_DIED: {
1586                 final int pid = msg.arg1;
1587                 final int uid = msg.arg2;
1588                 dispatchProcessDied(pid, uid);
1589                 break;
1590             }
1591             case DISPATCH_UIDS_CHANGED_MSG: {
1592                 dispatchUidsChanged();
1593             } break;
1594             }
1595         }
1596     }
1597
1598     final class MainHandler extends Handler {
1599         public MainHandler(Looper looper) {
1600             super(looper, null, true);
1601         }
1602
1603         @Override
1604         public void handleMessage(Message msg) {
1605             switch (msg.what) {
1606             case UPDATE_CONFIGURATION_MSG: {
1607                 final ContentResolver resolver = mContext.getContentResolver();
1608                 Settings.System.putConfiguration(resolver, (Configuration) msg.obj);
1609             } break;
1610             case GC_BACKGROUND_PROCESSES_MSG: {
1611                 synchronized (ActivityManagerService.this) {
1612                     performAppGcsIfAppropriateLocked();
1613                 }
1614             } break;
1615             case SERVICE_TIMEOUT_MSG: {
1616                 if (mDidDexOpt) {
1617                     mDidDexOpt = false;
1618                     Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1619                     nmsg.obj = msg.obj;
1620                     mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1621                     return;
1622                 }
1623                 mServices.serviceTimeout((ProcessRecord)msg.obj);
1624             } break;
1625             case UPDATE_TIME_ZONE: {
1626                 synchronized (ActivityManagerService.this) {
1627                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1628                         ProcessRecord r = mLruProcesses.get(i);
1629                         if (r.thread != null) {
1630                             try {
1631                                 r.thread.updateTimeZone();
1632                             } catch (RemoteException ex) {
1633                                 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1634                             }
1635                         }
1636                     }
1637                 }
1638             } break;
1639             case CLEAR_DNS_CACHE_MSG: {
1640                 synchronized (ActivityManagerService.this) {
1641                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1642                         ProcessRecord r = mLruProcesses.get(i);
1643                         if (r.thread != null) {
1644                             try {
1645                                 r.thread.clearDnsCache();
1646                             } catch (RemoteException ex) {
1647                                 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1648                             }
1649                         }
1650                     }
1651                 }
1652             } break;
1653             case UPDATE_HTTP_PROXY_MSG: {
1654                 ProxyInfo proxy = (ProxyInfo)msg.obj;
1655                 String host = "";
1656                 String port = "";
1657                 String exclList = "";
1658                 Uri pacFileUrl = Uri.EMPTY;
1659                 if (proxy != null) {
1660                     host = proxy.getHost();
1661                     port = Integer.toString(proxy.getPort());
1662                     exclList = proxy.getExclusionListAsString();
1663                     pacFileUrl = proxy.getPacFileUrl();
1664                 }
1665                 synchronized (ActivityManagerService.this) {
1666                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1667                         ProcessRecord r = mLruProcesses.get(i);
1668                         if (r.thread != null) {
1669                             try {
1670                                 r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1671                             } catch (RemoteException ex) {
1672                                 Slog.w(TAG, "Failed to update http proxy for: " +
1673                                         r.info.processName);
1674                             }
1675                         }
1676                     }
1677                 }
1678             } break;
1679             case PROC_START_TIMEOUT_MSG: {
1680                 if (mDidDexOpt) {
1681                     mDidDexOpt = false;
1682                     Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1683                     nmsg.obj = msg.obj;
1684                     mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1685                     return;
1686                 }
1687                 ProcessRecord app = (ProcessRecord)msg.obj;
1688                 synchronized (ActivityManagerService.this) {
1689                     processStartTimedOutLocked(app);
1690                 }
1691             } break;
1692             case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1693                 synchronized (ActivityManagerService.this) {
1694                     mStackSupervisor.doPendingActivityLaunchesLocked(true);
1695                 }
1696             } break;
1697             case KILL_APPLICATION_MSG: {
1698                 synchronized (ActivityManagerService.this) {
1699                     int appid = msg.arg1;
1700                     boolean restart = (msg.arg2 == 1);
1701                     Bundle bundle = (Bundle)msg.obj;
1702                     String pkg = bundle.getString("pkg");
1703                     String reason = bundle.getString("reason");
1704                     forceStopPackageLocked(pkg, appid, restart, false, true, false,
1705                             false, UserHandle.USER_ALL, reason);
1706                 }
1707             } break;
1708             case FINALIZE_PENDING_INTENT_MSG: {
1709                 ((PendingIntentRecord)msg.obj).completeFinalize();
1710             } break;
1711             case POST_HEAVY_NOTIFICATION_MSG: {
1712                 INotificationManager inm = NotificationManager.getService();
1713                 if (inm == null) {
1714                     return;
1715                 }
1716
1717                 ActivityRecord root = (ActivityRecord)msg.obj;
1718                 ProcessRecord process = root.app;
1719                 if (process == null) {
1720                     return;
1721                 }
1722
1723                 try {
1724                     Context context = mContext.createPackageContext(process.info.packageName, 0);
1725                     String text = mContext.getString(R.string.heavy_weight_notification,
1726                             context.getApplicationInfo().loadLabel(context.getPackageManager()));
1727                     Notification notification = new Notification.Builder(context)
1728                             .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
1729                             .setWhen(0)
1730                             .setOngoing(true)
1731                             .setTicker(text)
1732                             .setColor(mContext.getColor(
1733                                     com.android.internal.R.color.system_notification_accent_color))
1734                             .setContentTitle(text)
1735                             .setContentText(
1736                                     mContext.getText(R.string.heavy_weight_notification_detail))
1737                             .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
1738                                     root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
1739                                     new UserHandle(root.userId)))
1740                             .build();
1741                     try {
1742                         int[] outId = new int[1];
1743                         inm.enqueueNotificationWithTag("android", "android", null,
1744                                 R.string.heavy_weight_notification,
1745                                 notification, outId, root.userId);
1746                     } catch (RuntimeException e) {
1747                         Slog.w(ActivityManagerService.TAG,
1748                                 "Error showing notification for heavy-weight app", e);
1749                     } catch (RemoteException e) {
1750                     }
1751                 } catch (NameNotFoundException e) {
1752                     Slog.w(TAG, "Unable to create context for heavy notification", e);
1753                 }
1754             } break;
1755             case CANCEL_HEAVY_NOTIFICATION_MSG: {
1756                 INotificationManager inm = NotificationManager.getService();
1757                 if (inm == null) {
1758                     return;
1759                 }
1760                 try {
1761                     inm.cancelNotificationWithTag("android", null,
1762                             R.string.heavy_weight_notification,  msg.arg1);
1763                 } catch (RuntimeException e) {
1764                     Slog.w(ActivityManagerService.TAG,
1765                             "Error canceling notification for service", e);
1766                 } catch (RemoteException e) {
1767                 }
1768             } break;
1769             case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1770                 synchronized (ActivityManagerService.this) {
1771                     checkExcessivePowerUsageLocked(true);
1772                     removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1773                     Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1774                     sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1775                 }
1776             } break;
1777             case REPORT_MEM_USAGE_MSG: {
1778                 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1779                 Thread thread = new Thread() {
1780                     @Override public void run() {
1781                         reportMemUsage(memInfos);
1782                     }
1783                 };
1784                 thread.start();
1785                 break;
1786             }
1787             case REPORT_USER_SWITCH_MSG: {
1788                 dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1789                 break;
1790             }
1791             case CONTINUE_USER_SWITCH_MSG: {
1792                 continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1793                 break;
1794             }
1795             case USER_SWITCH_TIMEOUT_MSG: {
1796                 timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1797                 break;
1798             }
1799             case IMMERSIVE_MODE_LOCK_MSG: {
1800                 final boolean nextState = (msg.arg1 != 0);
1801                 if (mUpdateLock.isHeld() != nextState) {
1802                     if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
1803                             "Applying new update lock state '" + nextState
1804                             + "' for " + (ActivityRecord)msg.obj);
1805                     if (nextState) {
1806                         mUpdateLock.acquire();
1807                     } else {
1808                         mUpdateLock.release();
1809                     }
1810                 }
1811                 break;
1812             }
1813             case PERSIST_URI_GRANTS_MSG: {
1814                 writeGrantedUriPermissions();
1815                 break;
1816             }
1817             case REQUEST_ALL_PSS_MSG: {
1818                 synchronized (ActivityManagerService.this) {
1819                     requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1820                 }
1821                 break;
1822             }
1823             case START_PROFILES_MSG: {
1824                 synchronized (ActivityManagerService.this) {
1825                     startProfilesLocked();
1826                 }
1827                 break;
1828             }
1829             case UPDATE_TIME: {
1830                 synchronized (ActivityManagerService.this) {
1831                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1832                         ProcessRecord r = mLruProcesses.get(i);
1833                         if (r.thread != null) {
1834                             try {
1835                                 r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1836                             } catch (RemoteException ex) {
1837                                 Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1838                             }
1839                         }
1840                     }
1841                 }
1842                 break;
1843             }
1844             case SYSTEM_USER_START_MSG: {
1845                 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1846                         Integer.toString(msg.arg1), msg.arg1);
1847                 mSystemServiceManager.startUser(msg.arg1);
1848                 break;
1849             }
1850             case SYSTEM_USER_CURRENT_MSG: {
1851                 mBatteryStatsService.noteEvent(
1852                         BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1853                         Integer.toString(msg.arg2), msg.arg2);
1854                 mBatteryStatsService.noteEvent(
1855                         BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1856                         Integer.toString(msg.arg1), msg.arg1);
1857                 mSystemServiceManager.switchUser(msg.arg1);
1858                 break;
1859             }
1860             case ENTER_ANIMATION_COMPLETE_MSG: {
1861                 synchronized (ActivityManagerService.this) {
1862                     ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
1863                     if (r != null && r.app != null && r.app.thread != null) {
1864                         try {
1865                             r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1866                         } catch (RemoteException e) {
1867                         }
1868                     }
1869                 }
1870                 break;
1871             }
1872             case FINISH_BOOTING_MSG: {
1873                 if (msg.arg1 != 0) {
1874                     finishBooting();
1875                 }
1876                 if (msg.arg2 != 0) {
1877                     enableScreenAfterBoot();
1878                 }
1879                 break;
1880             }
1881             case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
1882                 try {
1883                     Locale l = (Locale) msg.obj;
1884                     IBinder service = ServiceManager.getService("mount");
1885                     IMountService mountService = IMountService.Stub.asInterface(service);
1886                     Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
1887                     mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
1888                 } catch (RemoteException e) {
1889                     Log.e(TAG, "Error storing locale for decryption UI", e);
1890                 }
1891                 break;
1892             }
1893             case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: {
1894                 synchronized (ActivityManagerService.this) {
1895                     int i = mTaskStackListeners.beginBroadcast();
1896                     while (i > 0) {
1897                         i--;
1898                         try {
1899                             // Make a one-way callback to the listener
1900                             mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged();
1901                         } catch (RemoteException e){
1902                             // Handled by the RemoteCallbackList
1903                         }
1904                     }
1905                     mTaskStackListeners.finishBroadcast();
1906                 }
1907                 break;
1908             }
1909             case NOTIFY_CLEARTEXT_NETWORK_MSG: {
1910                 final int uid = msg.arg1;
1911                 final byte[] firstPacket = (byte[]) msg.obj;
1912
1913                 synchronized (mPidsSelfLocked) {
1914                     for (int i = 0; i < mPidsSelfLocked.size(); i++) {
1915                         final ProcessRecord p = mPidsSelfLocked.valueAt(i);
1916                         if (p.uid == uid) {
1917                             try {
1918                                 p.thread.notifyCleartextNetwork(firstPacket);
1919                             } catch (RemoteException ignored) {
1920                             }
1921                         }
1922                     }
1923                 }
1924                 break;
1925             }
1926             case POST_DUMP_HEAP_NOTIFICATION_MSG: {
1927                 final String procName;
1928                 final int uid;
1929                 final long memLimit;
1930                 final String reportPackage;
1931                 synchronized (ActivityManagerService.this) {
1932                     procName = mMemWatchDumpProcName;
1933                     uid = mMemWatchDumpUid;
1934                     Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
1935                     if (val == null) {
1936                         val = mMemWatchProcesses.get(procName, 0);
1937                     }
1938                     if (val != null) {
1939                         memLimit = val.first;
1940                         reportPackage = val.second;
1941                     } else {
1942                         memLimit = 0;
1943                         reportPackage = null;
1944                     }
1945                 }
1946                 if (procName == null) {
1947                     return;
1948                 }
1949
1950                 if (DEBUG_PSS) Slog.d(TAG_PSS,
1951                         "Showing dump heap notification from " + procName + "/" + uid);
1952
1953                 INotificationManager inm = NotificationManager.getService();
1954                 if (inm == null) {
1955                     return;
1956                 }
1957
1958                 String text = mContext.getString(R.string.dump_heap_notification, procName);
1959
1960
1961                 Intent deleteIntent = new Intent();
1962                 deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
1963                 Intent intent = new Intent();
1964                 intent.setClassName("android", DumpHeapActivity.class.getName());
1965                 intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
1966                 intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
1967                 if (reportPackage != null) {
1968                     intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
1969                 }
1970                 int userId = UserHandle.getUserId(uid);
1971                 Notification notification = new Notification.Builder(mContext)
1972                         .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
1973                         .setWhen(0)
1974                         .setOngoing(true)
1975                         .setAutoCancel(true)
1976                         .setTicker(text)
1977                         .setColor(mContext.getColor(
1978                                 com.android.internal.R.color.system_notification_accent_color))
1979                         .setContentTitle(text)
1980                         .setContentText(
1981                                 mContext.getText(R.string.dump_heap_notification_detail))
1982                         .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
1983                                 intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
1984                                 new UserHandle(userId)))
1985                         .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
1986                                 deleteIntent, 0, UserHandle.OWNER))
1987                         .build();
1988
1989                 try {
1990                     int[] outId = new int[1];
1991                     inm.enqueueNotificationWithTag("android", "android", null,
1992                             R.string.dump_heap_notification,
1993                             notification, outId, userId);
1994                 } catch (RuntimeException e) {
1995                     Slog.w(ActivityManagerService.TAG,
1996                             "Error showing notification for dump heap", e);
1997                 } catch (RemoteException e) {
1998                 }
1999             } break;
2000             case DELETE_DUMPHEAP_MSG: {
2001                 revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2002                         DumpHeapActivity.JAVA_URI,
2003                         Intent.FLAG_GRANT_READ_URI_PERMISSION
2004                                 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2005                         UserHandle.myUserId());
2006                 synchronized (ActivityManagerService.this) {
2007                     mMemWatchDumpFile = null;
2008                     mMemWatchDumpProcName = null;
2009                     mMemWatchDumpPid = -1;
2010                     mMemWatchDumpUid = -1;
2011                 }
2012             } break;
2013             case FOREGROUND_PROFILE_CHANGED_MSG: {
2014                 dispatchForegroundProfileChanged(msg.arg1);
2015             } break;
2016             case REPORT_TIME_TRACKER_MSG: {
2017                 AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2018                 tracker.deliverResult(mContext);
2019             } break;
2020             case REPORT_USER_SWITCH_COMPLETE_MSG: {
2021                 dispatchUserSwitchComplete(msg.arg1);
2022             } break;
2023             case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2024                 IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2025                 try {
2026                     connection.shutdown();
2027                 } catch (RemoteException e) {
2028                     Slog.w(TAG, "Error shutting down UiAutomationConnection");
2029                 }
2030                 // Only a UiAutomation can set this flag and now that
2031                 // it is finished we make sure it is reset to its default.
2032                 mUserIsMonkey = false;
2033             } break;
2034             }
2035         }
2036     };
2037
2038     static final int COLLECT_PSS_BG_MSG = 1;
2039
2040     final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2041         @Override
2042         public void handleMessage(Message msg) {
2043             switch (msg.what) {
2044             case COLLECT_PSS_BG_MSG: {
2045                 long start = SystemClock.uptimeMillis();
2046                 MemInfoReader memInfo = null;
2047                 synchronized (ActivityManagerService.this) {
2048                     if (mFullPssPending) {
2049                         mFullPssPending = false;
2050                         memInfo = new MemInfoReader();
2051                     }
2052                 }
2053                 if (memInfo != null) {
2054                     updateCpuStatsNow();
2055                     long nativeTotalPss = 0;
2056                     synchronized (mProcessCpuTracker) {
2057                         final int N = mProcessCpuTracker.countStats();
2058                         for (int j=0; j<N; j++) {
2059                             ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
2060                             if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
2061                                 // This is definitely an application process; skip it.
2062                                 continue;
2063                             }
2064                             synchronized (mPidsSelfLocked) {
2065                                 if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
2066                                     // This is one of our own processes; skip it.
2067                                     continue;
2068                                 }
2069                             }
2070                             nativeTotalPss += Debug.getPss(st.pid, null, null);
2071                         }
2072                     }
2073                     memInfo.readMemInfo();
2074                     synchronized (ActivityManagerService.this) {
2075                         if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2076                                 + (SystemClock.uptimeMillis()-start) + "ms");
2077                         final long cachedKb = memInfo.getCachedSizeKb();
2078                         final long freeKb = memInfo.getFreeSizeKb();
2079                         final long zramKb = memInfo.getZramTotalSizeKb();
2080                         final long kernelKb = memInfo.getKernelUsedSizeKb();
2081                         EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2082                                 kernelKb*1024, nativeTotalPss*1024);
2083                         mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2084                                 nativeTotalPss);
2085                     }
2086                 }
2087
2088                 int num = 0;
2089                 long[] tmp = new long[1];
2090                 do {
2091                     ProcessRecord proc;
2092                     int procState;
2093                     int pid;
2094                     long lastPssTime;
2095                     synchronized (ActivityManagerService.this) {
2096                         if (mPendingPssProcesses.size() <= 0) {
2097                             if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2098                                     "Collected PSS of " + num + " processes in "
2099                                     + (SystemClock.uptimeMillis() - start) + "ms");
2100                             mPendingPssProcesses.clear();
2101                             return;
2102                         }
2103                         proc = mPendingPssProcesses.remove(0);
2104                         procState = proc.pssProcState;
2105                         lastPssTime = proc.lastPssTime;
2106                         if (proc.thread != null && procState == proc.setProcState
2107                                 && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2108                                         < SystemClock.uptimeMillis()) {
2109                             pid = proc.pid;
2110                         } else {
2111                             proc = null;
2112                             pid = 0;
2113                         }
2114                     }
2115                     if (proc != null) {
2116                         long pss = Debug.getPss(pid, tmp, null);
2117                         synchronized (ActivityManagerService.this) {
2118                             if (pss != 0 && proc.thread != null && proc.setProcState == procState
2119                                     && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2120                                 num++;
2121                                 recordPssSampleLocked(proc, procState, pss, tmp[0],
2122                                         SystemClock.uptimeMillis());
2123                             }
2124                         }
2125                     }
2126                 } while (true);
2127             }
2128             }
2129         }
2130     };
2131
2132     public void setSystemProcess() {
2133         try {
2134             ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2135             ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2136             ServiceManager.addService("meminfo", new MemBinder(this));
2137             ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2138             ServiceManager.addService("dbinfo", new DbBinder(this));
2139             if (MONITOR_CPU_USAGE) {
2140                 ServiceManager.addService("cpuinfo", new CpuBinder(this));
2141             }
2142             ServiceManager.addService("permission", new PermissionController(this));
2143             ServiceManager.addService("processinfo", new ProcessInfoService(this));
2144
2145             ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2146                     "android", STOCK_PM_FLAGS);
2147             mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2148
2149             synchronized (this) {
2150                 ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2151                 app.persistent = true;
2152                 app.pid = MY_PID;
2153                 app.maxAdj = ProcessList.SYSTEM_ADJ;
2154                 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2155                 synchronized (mPidsSelfLocked) {
2156                     mPidsSelfLocked.put(app.pid, app);
2157                 }
2158                 updateLruProcessLocked(app, false, null);
2159                 updateOomAdjLocked();
2160             }
2161         } catch (PackageManager.NameNotFoundException e) {
2162             throw new RuntimeException(
2163                     "Unable to find android system package", e);
2164         }
2165     }
2166
2167     public void setWindowManager(WindowManagerService wm) {
2168         mWindowManager = wm;
2169         mStackSupervisor.setWindowManager(wm);
2170     }
2171
2172     public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2173         mUsageStatsService = usageStatsManager;
2174     }
2175
2176     public void startObservingNativeCrashes() {
2177         final NativeCrashListener ncl = new NativeCrashListener(this);
2178         ncl.start();
2179     }
2180
2181     public IAppOpsService getAppOpsService() {
2182         return mAppOpsService;
2183     }
2184
2185     static class MemBinder extends Binder {
2186         ActivityManagerService mActivityManagerService;
2187         MemBinder(ActivityManagerService activityManagerService) {
2188             mActivityManagerService = activityManagerService;
2189         }
2190
2191         @Override
2192         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2193             if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2194                     != PackageManager.PERMISSION_GRANTED) {
2195                 pw.println("Permission Denial: can't dump meminfo from from pid="
2196                         + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2197                         + " without permission " + android.Manifest.permission.DUMP);
2198                 return;
2199             }
2200
2201             mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2202         }
2203     }
2204
2205     static class GraphicsBinder extends Binder {
2206         ActivityManagerService mActivityManagerService;
2207         GraphicsBinder(ActivityManagerService activityManagerService) {
2208             mActivityManagerService = activityManagerService;
2209         }
2210
2211         @Override
2212         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2213             if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2214                     != PackageManager.PERMISSION_GRANTED) {
2215                 pw.println("Permission Denial: can't dump gfxinfo from from pid="
2216                         + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2217                         + " without permission " + android.Manifest.permission.DUMP);
2218                 return;
2219             }
2220
2221             mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2222         }
2223     }
2224
2225     static class DbBinder extends Binder {
2226         ActivityManagerService mActivityManagerService;
2227         DbBinder(ActivityManagerService activityManagerService) {
2228             mActivityManagerService = activityManagerService;
2229         }
2230
2231         @Override
2232         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2233             if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2234                     != PackageManager.PERMISSION_GRANTED) {
2235                 pw.println("Permission Denial: can't dump dbinfo from from pid="
2236                         + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2237                         + " without permission " + android.Manifest.permission.DUMP);
2238                 return;
2239             }
2240
2241             mActivityManagerService.dumpDbInfo(fd, pw, args);
2242         }
2243     }
2244
2245     static class CpuBinder extends Binder {
2246         ActivityManagerService mActivityManagerService;
2247         CpuBinder(ActivityManagerService activityManagerService) {
2248             mActivityManagerService = activityManagerService;
2249         }
2250
2251         @Override
2252         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2253             if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2254                     != PackageManager.PERMISSION_GRANTED) {
2255                 pw.println("Permission Denial: can't dump cpuinfo from from pid="
2256                         + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2257                         + " without permission " + android.Manifest.permission.DUMP);
2258                 return;
2259             }
2260
2261             synchronized (mActivityManagerService.mProcessCpuTracker) {
2262                 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2263                 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2264                         SystemClock.uptimeMillis()));
2265             }
2266         }
2267     }
2268
2269     public static final class Lifecycle extends SystemService {
2270         private final ActivityManagerService mService;
2271
2272         public Lifecycle(Context context) {
2273             super(context);
2274             mService = new ActivityManagerService(context);
2275         }
2276
2277         @Override
2278         public void onStart() {
2279             mService.start();
2280         }
2281
2282         public ActivityManagerService getService() {
2283             return mService;
2284         }
2285     }
2286
2287     // Note: This method is invoked on the main thread but may need to attach various
2288     // handlers to other threads.  So take care to be explicit about the looper.
2289     public ActivityManagerService(Context systemContext) {
2290         mContext = systemContext;
2291         mFactoryTest = FactoryTest.getMode();
2292         mSystemThread = ActivityThread.currentActivityThread();
2293
2294         Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2295
2296         mHandlerThread = new ServiceThread(TAG,
2297                 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2298         mHandlerThread.start();
2299         mHandler = new MainHandler(mHandlerThread.getLooper());
2300         mUiHandler = new UiHandler();
2301
2302         mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2303                 "foreground", BROADCAST_FG_TIMEOUT, false);
2304         mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2305                 "background", BROADCAST_BG_TIMEOUT, true);
2306         mBroadcastQueues[0] = mFgBroadcastQueue;
2307         mBroadcastQueues[1] = mBgBroadcastQueue;
2308
2309         mServices = new ActiveServices(this);
2310         mProviderMap = new ProviderMap(this);
2311
2312         // TODO: Move creation of battery stats service outside of activity manager service.
2313         File dataDir = Environment.getDataDirectory();
2314         File systemDir = new File(dataDir, "system");
2315         systemDir.mkdirs();
2316         mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2317         mBatteryStatsService.getActiveStatistics().readLocked();
2318         mBatteryStatsService.scheduleWriteToDisk();
2319         mOnBattery = DEBUG_POWER ? true
2320                 : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2321         mBatteryStatsService.getActiveStatistics().setCallback(this);
2322
2323         mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2324
2325         mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2326
2327         mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2328
2329         // User 0 is the first and only user that runs at boot.
2330         mStartedUsers.put(UserHandle.USER_OWNER, new UserState(UserHandle.OWNER, true));
2331         mUserLru.add(UserHandle.USER_OWNER);
2332         updateStartedUserArrayLocked();
2333
2334         GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2335             ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2336
2337         mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2338
2339         mConfiguration.setToDefaults();
2340         mConfiguration.setLocale(Locale.getDefault());
2341
2342         mConfigurationSeq = mConfiguration.seq = 1;
2343         mProcessCpuTracker.init();
2344
2345         mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2346         mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2347         mRecentTasks = new RecentTasks(this);
2348         mStackSupervisor = new ActivityStackSupervisor(this, mRecentTasks);
2349         mTaskPersister = new TaskPersister(systemDir, mStackSupervisor, mRecentTasks);
2350
2351         mProcessCpuThread = new Thread("CpuTracker") {
2352             @Override
2353             public void run() {
2354                 while (true) {
2355                     try {
2356                         try {
2357                             synchronized(this) {
2358                                 final long now = SystemClock.uptimeMillis();
2359                                 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2360                                 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2361                                 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2362                                 //        + ", write delay=" + nextWriteDelay);
2363                                 if (nextWriteDelay < nextCpuDelay) {
2364                                     nextCpuDelay = nextWriteDelay;
2365                                 }
2366                                 if (nextCpuDelay > 0) {
2367                                     mProcessCpuMutexFree.set(true);
2368                                     this.wait(nextCpuDelay);
2369                                 }
2370                             }
2371                         } catch (InterruptedException e) {
2372                         }
2373                         updateCpuStatsNow();
2374                     } catch (Exception e) {
2375                         Slog.e(TAG, "Unexpected exception collecting process stats", e);
2376                     }
2377                 }
2378             }
2379         };
2380
2381         Watchdog.getInstance().addMonitor(this);
2382         Watchdog.getInstance().addThread(mHandler);
2383     }
2384
2385     public void setSystemServiceManager(SystemServiceManager mgr) {
2386         mSystemServiceManager = mgr;
2387     }
2388
2389     public void setInstaller(Installer installer) {
2390         mInstaller = installer;
2391     }
2392
2393     private void start() {
2394         Process.removeAllProcessGroups();
2395         mProcessCpuThread.start();
2396
2397         mBatteryStatsService.publish(mContext);
2398         mAppOpsService.publish(mContext);
2399         Slog.d("AppOps", "AppOpsService published");
2400         LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2401     }
2402
2403     public void initPowerManagement() {
2404         mStackSupervisor.initPowerManagement();
2405         mBatteryStatsService.initPowerManagement();
2406         mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2407         PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2408         mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2409         mVoiceWakeLock.setReferenceCounted(false);
2410     }
2411
2412     @Override
2413     public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2414             throws RemoteException {
2415         if (code == SYSPROPS_TRANSACTION) {
2416             // We need to tell all apps about the system property change.
2417             ArrayList<IBinder> procs = new ArrayList<IBinder>();
2418             synchronized(this) {
2419                 final int NP = mProcessNames.getMap().size();
2420                 for (int ip=0; ip<NP; ip++) {
2421                     SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2422                     final int NA = apps.size();
2423                     for (int ia=0; ia<NA; ia++) {
2424                         ProcessRecord app = apps.valueAt(ia);
2425                         if (app.thread != null) {
2426                             procs.add(app.thread.asBinder());
2427                         }
2428                     }
2429                 }
2430             }
2431
2432             int N = procs.size();
2433             for (int i=0; i<N; i++) {
2434                 Parcel data2 = Parcel.obtain();
2435                 try {
2436                     procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2437                 } catch (RemoteException e) {
2438                 }
2439                 data2.recycle();
2440             }
2441         }
2442         try {
2443             return super.onTransact(code, data, reply, flags);
2444         } catch (RuntimeException e) {
2445             // The activity manager only throws security exceptions, so let's
2446             // log all others.
2447             if (!(e instanceof SecurityException)) {
2448                 Slog.wtf(TAG, "Activity Manager Crash", e);
2449             }
2450             throw e;
2451         }
2452     }
2453
2454     void updateCpuStats() {
2455         final long now = SystemClock.uptimeMillis();
2456         if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2457             return;
2458         }
2459         if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2460             synchronized (mProcessCpuThread) {
2461                 mProcessCpuThread.notify();
2462             }
2463         }
2464     }
2465
2466     void updateCpuStatsNow() {
2467         synchronized (mProcessCpuTracker) {
2468             mProcessCpuMutexFree.set(false);
2469             final long now = SystemClock.uptimeMillis();
2470             boolean haveNewCpuStats = false;
2471
2472             if (MONITOR_CPU_USAGE &&
2473                     mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2474                 mLastCpuTime.set(now);
2475                 mProcessCpuTracker.update();
2476                 if (mProcessCpuTracker.hasGoodLastStats()) {
2477                     haveNewCpuStats = true;
2478                     //Slog.i(TAG, mProcessCpu.printCurrentState());
2479                     //Slog.i(TAG, "Total CPU usage: "
2480                     //        + mProcessCpu.getTotalCpuPercent() + "%");
2481
2482                     // Slog the cpu usage if the property is set.
2483                     if ("true".equals(SystemProperties.get("events.cpu"))) {
2484                         int user = mProcessCpuTracker.getLastUserTime();
2485                         int system = mProcessCpuTracker.getLastSystemTime();
2486                         int iowait = mProcessCpuTracker.getLastIoWaitTime();
2487                         int irq = mProcessCpuTracker.getLastIrqTime();
2488                         int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2489                         int idle = mProcessCpuTracker.getLastIdleTime();
2490
2491                         int total = user + system + iowait + irq + softIrq + idle;
2492                         if (total == 0) total = 1;
2493
2494                         EventLog.writeEvent(EventLogTags.CPU,
2495                                 ((user+system+iowait+irq+softIrq) * 100) / total,
2496                                 (user * 100) / total,
2497                                 (system * 100) / total,
2498                                 (iowait * 100) / total,
2499                                 (irq * 100) / total,
2500                                 (softIrq * 100) / total);
2501                     }
2502                 }
2503             }
2504
2505             final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2506             synchronized(bstats) {
2507                 synchronized(mPidsSelfLocked) {
2508                     if (haveNewCpuStats) {
2509                         if (bstats.startAddingCpuLocked()) {
2510                             int totalUTime = 0;
2511                             int totalSTime = 0;
2512                             final int N = mProcessCpuTracker.countStats();
2513                             for (int i=0; i<N; i++) {
2514                                 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2515                                 if (!st.working) {
2516                                     continue;
2517                                 }
2518                                 ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2519                                 totalUTime += st.rel_utime;
2520                                 totalSTime += st.rel_stime;
2521                                 if (pr != null) {
2522                                     BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2523                                     if (ps == null || !ps.isActive()) {
2524                                         pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2525                                                 pr.info.uid, pr.processName);
2526                                     }
2527                                     ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2528                                     pr.curCpuTime += st.rel_utime + st.rel_stime;
2529                                 } else {
2530                                     BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2531                                     if (ps == null || !ps.isActive()) {
2532                                         st.batteryStats = ps = bstats.getProcessStatsLocked(
2533                                                 bstats.mapUid(st.uid), st.name);
2534                                     }
2535                                     ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2536                                 }
2537                             }
2538                             final int userTime = mProcessCpuTracker.getLastUserTime();
2539                             final int systemTime = mProcessCpuTracker.getLastSystemTime();
2540                             final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
2541                             final int irqTime = mProcessCpuTracker.getLastIrqTime();
2542                             final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
2543                             final int idleTime = mProcessCpuTracker.getLastIdleTime();
2544                             bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
2545                                     systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
2546                         }
2547                     }
2548                 }
2549
2550                 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2551                     mLastWriteTime = now;
2552                     mBatteryStatsService.scheduleWriteToDisk();
2553                 }
2554             }
2555         }
2556     }
2557
2558     @Override
2559     public void batteryNeedsCpuUpdate() {
2560         updateCpuStatsNow();
2561     }
2562
2563     @Override
2564     public void batteryPowerChanged(boolean onBattery) {
2565         // When plugging in, update the CPU stats first before changing
2566         // the plug state.
2567         updateCpuStatsNow();
2568         synchronized (this) {
2569             synchronized(mPidsSelfLocked) {
2570                 mOnBattery = DEBUG_POWER ? true : onBattery;
2571             }
2572         }
2573     }
2574
2575     @Override
2576     public void batterySendBroadcast(Intent intent) {
2577         broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
2578                 AppOpsManager.OP_NONE, null, false, false,
2579                 -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
2580     }
2581
2582     /**
2583      * Initialize the application bind args. These are passed to each
2584      * process when the bindApplication() IPC is sent to the process. They're
2585      * lazily setup to make sure the services are running when they're asked for.
2586      */
2587     private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2588         if (mAppBindArgs == null) {
2589             mAppBindArgs = new HashMap<>();
2590
2591             // Isolated processes won't get this optimization, so that we don't
2592             // violate the rules about which services they have access to.
2593             if (!isolated) {
2594                 // Setup the application init args
2595                 mAppBindArgs.put("package", ServiceManager.getService("package"));
2596                 mAppBindArgs.put("window", ServiceManager.getService("window"));
2597                 mAppBindArgs.put(Context.ALARM_SERVICE,
2598                         ServiceManager.getService(Context.ALARM_SERVICE));
2599             }
2600         }
2601         return mAppBindArgs;
2602     }
2603
2604     final void setFocusedActivityLocked(ActivityRecord r, String reason) {
2605         if (r != null && mFocusedActivity != r) {
2606             if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: r=" + r);
2607             ActivityRecord last = mFocusedActivity;
2608             mFocusedActivity = r;
2609             if (r.task.taskType != ActivityRecord.HOME_ACTIVITY_TYPE
2610                     && r.task.taskType != ActivityRecord.RECENTS_ACTIVITY_TYPE) {
2611                 if (mCurAppTimeTracker != r.appTimeTracker) {
2612                     // We are switching app tracking.  Complete the current one.
2613                     if (mCurAppTimeTracker != null) {
2614                         mCurAppTimeTracker.stop();
2615                         mHandler.obtainMessage(REPORT_TIME_TRACKER_MSG,
2616                                 mCurAppTimeTracker).sendToTarget();
2617                         mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
2618                         mCurAppTimeTracker = null;
2619                     }
2620                     if (r.appTimeTracker != null) {
2621                         mCurAppTimeTracker = r.appTimeTracker;
2622                         startTimeTrackingFocusedActivityLocked();
2623                     }
2624                 } else {
2625                     startTimeTrackingFocusedActivityLocked();
2626                 }
2627             } else {
2628                 r.appTimeTracker = null;
2629             }
2630             if (r.task != null && r.task.voiceInteractor != null) {
2631                 startRunningVoiceLocked(r.task.voiceSession, r.info.applicationInfo.uid);
2632             } else {
2633                 finishRunningVoiceLocked();
2634                 if (last != null && last.task.voiceSession != null) {
2635                     // We had been in a voice interaction session, but now focused has
2636                     // move to something different.  Just finish the session, we can't
2637                     // return to it and retain the proper state and synchronization with
2638                     // the voice interaction service.
2639                     finishVoiceTask(last.task.voiceSession);
2640                 }
2641             }
2642             if (mStackSupervisor.setFocusedStack(r, reason + " setFocusedActivity")) {
2643                 mWindowManager.setFocusedApp(r.appToken, true);
2644             }
2645             applyUpdateLockStateLocked(r);
2646             if (mFocusedActivity.userId != mLastFocusedUserId) {
2647                 mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2648                 mHandler.sendMessage(mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG,
2649                         mFocusedActivity.userId, 0));
2650                 mLastFocusedUserId = mFocusedActivity.userId;
2651             }
2652         }
2653         EventLog.writeEvent(EventLogTags.AM_FOCUSED_ACTIVITY,
2654                 mFocusedActivity == null ? -1 : mFocusedActivity.userId,
2655                 mFocusedActivity == null ? "NULL" : mFocusedActivity.shortComponentName);
2656     }
2657
2658     final void clearFocusedActivity(ActivityRecord r) {
2659         if (mFocusedActivity == r) {
2660             ActivityStack stack = mStackSupervisor.getFocusedStack();
2661             if (stack != null) {
2662                 ActivityRecord top = stack.topActivity();
2663                 if (top != null && top.userId != mLastFocusedUserId) {
2664                     mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2665                     mHandler.sendMessage(mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG,
2666                                     top.userId, 0));
2667                     mLastFocusedUserId = top.userId;
2668                 }
2669             }
2670             mFocusedActivity = null;
2671             EventLog.writeEvent(EventLogTags.AM_FOCUSED_ACTIVITY, -1, "NULL");
2672         }
2673     }
2674
2675     @Override
2676     public void setFocusedStack(int stackId) {
2677         if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
2678         synchronized (ActivityManagerService.this) {
2679             ActivityStack stack = mStackSupervisor.getStack(stackId);
2680             if (stack != null) {
2681                 ActivityRecord r = stack.topRunningActivityLocked(null);
2682                 if (r != null) {
2683                     setFocusedActivityLocked(r, "setFocusedStack");
2684                     mStackSupervisor.resumeTopActivitiesLocked(stack, null, null);
2685                 }
2686             }
2687         }
2688     }
2689
2690     /** Sets the task stack listener that gets callbacks when a task stack changes. */
2691     @Override
2692     public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
2693         synchronized (ActivityManagerService.this) {
2694             if (listener != null) {
2695                 mTaskStackListeners.register(listener);
2696             }
2697         }
2698     }
2699
2700     @Override
2701     public void notifyActivityDrawn(IBinder token) {
2702         if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
2703         synchronized (this) {
2704             ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
2705             if (r != null) {
2706                 r.task.stack.notifyActivityDrawnLocked(r);
2707             }
2708         }
2709     }
2710
2711     final void applyUpdateLockStateLocked(ActivityRecord r) {
2712         // Modifications to the UpdateLock state are done on our handler, outside
2713         // the activity manager's locks.  The new state is determined based on the
2714         // state *now* of the relevant activity record.  The object is passed to
2715         // the handler solely for logging detail, not to be consulted/modified.
2716         final boolean nextState = r != null && r.immersive;
2717         mHandler.sendMessage(
2718                 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2719     }
2720
2721     final void showAskCompatModeDialogLocked(ActivityRecord r) {
2722         Message msg = Message.obtain();
2723         msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2724         msg.obj = r.task.askedCompatMode ? null : r;
2725         mUiHandler.sendMessage(msg);
2726     }
2727
2728     private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2729             String what, Object obj, ProcessRecord srcApp) {
2730         app.lastActivityTime = now;
2731
2732         if (app.activities.size() > 0) {
2733             // Don't want to touch dependent processes that are hosting activities.
2734             return index;
2735         }
2736
2737         int lrui = mLruProcesses.lastIndexOf(app);
2738         if (lrui < 0) {
2739             Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2740                     + what + " " + obj + " from " + srcApp);
2741             return index;
2742         }
2743
2744         if (lrui >= index) {
2745             // Don't want to cause this to move dependent processes *back* in the
2746             // list as if they were less frequently used.
2747             return index;
2748         }
2749
2750         if (lrui >= mLruProcessActivityStart) {
2751             // Don't want to touch dependent processes that are hosting activities.
2752             return index;
2753         }
2754
2755         mLruProcesses.remove(lrui);
2756         if (index > 0) {
2757             index--;
2758         }
2759         if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
2760                 + " in LRU list: " + app);
2761         mLruProcesses.add(index, app);
2762         return index;
2763     }
2764
2765     private static void killProcessGroup(int uid, int pid) {
2766         Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
2767         Process.killProcessGroup(uid, pid);
2768         Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
2769     }
2770
2771     final void removeLruProcessLocked(ProcessRecord app) {
2772         int lrui = mLruProcesses.lastIndexOf(app);
2773         if (lrui >= 0) {
2774             if (!app.killed) {
2775                 Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
2776                 Process.killProcessQuiet(app.pid);
2777                 killProcessGroup(app.info.uid, app.pid);
2778             }
2779             if (lrui <= mLruProcessActivityStart) {
2780                 mLruProcessActivityStart--;
2781             }
2782             if (lrui <= mLruProcessServiceStart) {
2783                 mLruProcessServiceStart--;
2784             }
2785             mLruProcesses.remove(lrui);
2786         }
2787     }
2788
2789     final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2790             ProcessRecord client) {
2791         final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2792                 || app.treatLikeActivity;
2793         final boolean hasService = false; // not impl yet. app.services.size() > 0;
2794         if (!activityChange && hasActivity) {
2795             // The process has activities, so we are only allowing activity-based adjustments
2796             // to move it.  It should be kept in the front of the list with other
2797             // processes that have activities, and we don't want those to change their
2798             // order except due to activity operations.
2799             return;
2800         }
2801
2802         mLruSeq++;
2803         final long now = SystemClock.uptimeMillis();
2804         app.lastActivityTime = now;
2805
2806         // First a quick reject: if the app is already at the position we will
2807         // put it, then there is nothing to do.
2808         if (hasActivity) {
2809             final int N = mLruProcesses.size();
2810             if (N > 0 && mLruProcesses.get(N-1) == app) {
2811                 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
2812                 return;
2813             }
2814         } else {
2815             if (mLruProcessServiceStart > 0
2816                     && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2817                 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
2818                 return;
2819             }
2820         }
2821
2822         int lrui = mLruProcesses.lastIndexOf(app);
2823
2824         if (app.persistent && lrui >= 0) {
2825             // We don't care about the position of persistent processes, as long as
2826             // they are in the list.
2827             if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
2828             return;
2829         }
2830
2831         /* In progress: compute new position first, so we can avoid doing work
2832            if the process is not actually going to move.  Not yet working.
2833         int addIndex;
2834         int nextIndex;
2835         boolean inActivity = false, inService = false;
2836         if (hasActivity) {
2837             // Process has activities, put it at the very tipsy-top.
2838             addIndex = mLruProcesses.size();
2839             nextIndex = mLruProcessServiceStart;
2840             inActivity = true;
2841         } else if (hasService) {
2842             // Process has services, put it at the top of the service list.
2843             addIndex = mLruProcessActivityStart;
2844             nextIndex = mLruProcessServiceStart;
2845             inActivity = true;
2846             inService = true;
2847         } else  {
2848             // Process not otherwise of interest, it goes to the top of the non-service area.
2849             addIndex = mLruProcessServiceStart;
2850             if (client != null) {
2851                 int clientIndex = mLruProcesses.lastIndexOf(client);
2852                 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2853                         + app);
2854                 if (clientIndex >= 0 && addIndex > clientIndex) {
2855                     addIndex = clientIndex;
2856                 }
2857             }
2858             nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2859         }
2860
2861         Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2862                 + mLruProcessActivityStart + "): " + app);
2863         */
2864
2865         if (lrui >= 0) {
2866             if (lrui < mLruProcessActivityStart) {
2867                 mLruProcessActivityStart--;
2868             }
2869             if (lrui < mLruProcessServiceStart) {
2870                 mLruProcessServiceStart--;
2871             }
2872             /*
2873             if (addIndex > lrui) {
2874                 addIndex--;
2875             }
2876             if (nextIndex > lrui) {
2877                 nextIndex--;
2878             }
2879             */
2880             mLruProcesses.remove(lrui);
2881         }
2882
2883         /*
2884         mLruProcesses.add(addIndex, app);
2885         if (inActivity) {
2886             mLruProcessActivityStart++;
2887         }
2888         if (inService) {
2889             mLruProcessActivityStart++;
2890         }
2891         */
2892
2893         int nextIndex;
2894         if (hasActivity) {
2895             final int N = mLruProcesses.size();
2896             if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
2897                 // Process doesn't have activities, but has clients with
2898                 // activities...  move it up, but one below the top (the top
2899                 // should always have a real activity).
2900                 if (DEBUG_LRU) Slog.d(TAG_LRU,
2901                         "Adding to second-top of LRU activity list: " + app);
2902                 mLruProcesses.add(N - 1, app);
2903                 // To keep it from spamming the LRU list (by making a bunch of clients),
2904                 // we will push down any other entries owned by the app.
2905                 final int uid = app.info.uid;
2906                 for (int i = N - 2; i > mLruProcessActivityStart; i--) {
2907                     ProcessRecord subProc = mLruProcesses.get(i);
2908                     if (subProc.info.uid == uid) {
2909                         // We want to push this one down the list.  If the process after
2910                         // it is for the same uid, however, don't do so, because we don't
2911                         // want them internally to be re-ordered.
2912                         if (mLruProcesses.get(i - 1).info.uid != uid) {
2913                             if (DEBUG_LRU) Slog.d(TAG_LRU,
2914                                     "Pushing uid " + uid + " swapping at " + i + ": "
2915                                     + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
2916                             ProcessRecord tmp = mLruProcesses.get(i);
2917                             mLruProcesses.set(i, mLruProcesses.get(i - 1));
2918                             mLruProcesses.set(i - 1, tmp);
2919                             i--;
2920                         }
2921                     } else {
2922                         // A gap, we can stop here.
2923                         break;
2924                     }
2925                 }
2926             } else {
2927                 // Process has activities, put it at the very tipsy-top.
2928                 if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
2929                 mLruProcesses.add(app);
2930             }
2931             nextIndex = mLruProcessServiceStart;
2932         } else if (hasService) {
2933             // Process has services, put it at the top of the service list.
2934             if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
2935             mLruProcesses.add(mLruProcessActivityStart, app);
2936             nextIndex = mLruProcessServiceStart;
2937             mLruProcessActivityStart++;
2938         } else  {
2939             // Process not otherwise of interest, it goes to the top of the non-service area.
2940             int index = mLruProcessServiceStart;
2941             if (client != null) {
2942                 // If there is a client, don't allow the process to be moved up higher
2943                 // in the list than that client.
2944                 int clientIndex = mLruProcesses.lastIndexOf(client);
2945                 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
2946                         + " when updating " + app);
2947                 if (clientIndex <= lrui) {
2948                     // Don't allow the client index restriction to push it down farther in the
2949                     // list than it already is.
2950                     clientIndex = lrui;
2951                 }
2952                 if (clientIndex >= 0 && index > clientIndex) {
2953                     index = clientIndex;
2954                 }
2955             }
2956             if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
2957             mLruProcesses.add(index, app);
2958             nextIndex = index-1;
2959             mLruProcessActivityStart++;
2960             mLruProcessServiceStart++;
2961         }
2962
2963         // If the app is currently using a content provider or service,
2964         // bump those processes as well.
2965         for (int j=app.connections.size()-1; j>=0; j--) {
2966             ConnectionRecord cr = app.connections.valueAt(j);
2967             if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2968                     && cr.binding.service.app != null
2969                     && cr.binding.service.app.lruSeq != mLruSeq
2970                     && !cr.binding.service.app.persistent) {
2971                 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2972                         "service connection", cr, app);
2973             }
2974         }
2975         for (int j=app.conProviders.size()-1; j>=0; j--) {
2976             ContentProviderRecord cpr = app.conProviders.get(j).provider;
2977             if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2978                 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2979                         "provider reference", cpr, app);
2980             }
2981         }
2982     }
2983
2984     final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2985         if (uid == Process.SYSTEM_UID) {
2986             // The system gets to run in any process.  If there are multiple
2987             // processes with the same uid, just pick the first (this
2988             // should never happen).
2989             SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2990             if (procs == null) return null;
2991             final int procCount = procs.size();
2992             for (int i = 0; i < procCount; i++) {
2993                 final int procUid = procs.keyAt(i);
2994                 if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
2995                     // Don't use an app process or different user process for system component.
2996                     continue;
2997                 }
2998                 return procs.valueAt(i);
2999             }
3000         }
3001         ProcessRecord proc = mProcessNames.get(processName, uid);
3002         if (false && proc != null && !keepIfLarge
3003                 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3004                 && proc.lastCachedPss >= 4000) {
3005             // Turn this condition on to cause killing to happen regularly, for testing.
3006             if (proc.baseProcessTracker != null) {
3007                 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3008             }
3009             proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3010         } else if (proc != null && !keepIfLarge
3011                 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3012                 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3013             if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3014             if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3015                 if (proc.baseProcessTracker != null) {
3016                     proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3017                 }
3018                 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3019             }
3020         }
3021         return proc;
3022     }
3023
3024     void ensurePackageDexOpt(String packageName) {
3025         IPackageManager pm = AppGlobals.getPackageManager();
3026         try {
3027             if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) {
3028                 mDidDexOpt = true;
3029             }
3030         } catch (RemoteException e) {
3031         }
3032     }
3033
3034     boolean isNextTransitionForward() {
3035         int transit = mWindowManager.getPendingAppTransition();
3036         return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
3037                 || transit == AppTransition.TRANSIT_TASK_OPEN
3038                 || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
3039     }
3040
3041     int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3042             String processName, String abiOverride, int uid, Runnable crashHandler) {
3043         synchronized(this) {
3044             ApplicationInfo info = new ApplicationInfo();
3045             // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3046             // For isolated processes, the former contains the parent's uid and the latter the
3047             // actual uid of the isolated process.
3048             // In the special case introduced by this method (which is, starting an isolated
3049             // process directly from the SystemServer without an actual parent app process) the
3050             // closest thing to a parent's uid is SYSTEM_UID.
3051             // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3052             // the |isolated| logic in the ProcessRecord constructor.
3053             info.uid = Process.SYSTEM_UID;
3054             info.processName = processName;
3055             info.className = entryPoint;
3056             info.packageName = "android";
3057             ProcessRecord proc = startProcessLocked(processName, info /* info */,
3058                     false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
3059                     null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3060                     uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3061                     crashHandler);
3062             return proc != null ? proc.pid : 0;
3063         }
3064     }
3065
3066     final ProcessRecord startProcessLocked(String processName,
3067             ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3068             String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3069             boolean isolated, boolean keepIfLarge) {
3070         return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3071                 hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3072                 null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3073                 null /* crashHandler */);
3074     }
3075
3076     final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3077             boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3078             boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3079             String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3080         long startTime = SystemClock.elapsedRealtime();
3081         ProcessRecord app;
3082         if (!isolated) {
3083             app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3084             checkTime(startTime, "startProcess: after getProcessRecord");
3085
3086             if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3087                 // If we are in the background, then check to see if this process
3088                 // is bad.  If so, we will just silently fail.
3089                 if (mBadProcesses.get(info.processName, info.uid) != null) {
3090                     if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3091                             + "/" + info.processName);
3092                     return null;
3093                 }
3094             } else {
3095                 // When the user is explicitly starting a process, then clear its
3096                 // crash count so that we won't make it bad until they see at
3097                 // least one crash dialog again, and make the process good again
3098                 // if it had been bad.
3099                 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3100                         + "/" + info.processName);
3101                 mProcessCrashTimes.remove(info.processName, info.uid);
3102                 if (mBadProcesses.get(info.processName, info.uid) != null) {
3103                     EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3104                             UserHandle.getUserId(info.uid), info.uid,
3105                             info.processName);
3106                     mBadProcesses.remove(info.processName, info.uid);
3107                     if (app != null) {
3108                         app.bad = false;
3109                     }
3110                 }
3111             }
3112         } else {
3113             // If this is an isolated process, it can't re-use an existing process.
3114             app = null;
3115         }
3116
3117         // We don't have to do anything more if:
3118         // (1) There is an existing application record; and
3119         // (2) The caller doesn't think it is dead, OR there is no thread
3120         //     object attached to it so we know it couldn't have crashed; and
3121         // (3) There is a pid assigned to it, so it is either starting or
3122         //     already running.
3123         if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3124                 + " app=" + app + " knownToBeDead=" + knownToBeDead
3125                 + " thread=" + (app != null ? app.thread : null)
3126                 + " pid=" + (app != null ? app.pid : -1));
3127         if (app != null && app.pid > 0) {
3128             if (!knownToBeDead || app.thread == null) {
3129                 // We already have the app running, or are waiting for it to
3130                 // come up (we have a pid but not yet its thread), so keep it.
3131                 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3132                 // If this is a new package in the process, add the package to the list
3133                 app.addPackage(info.packageName, info.versionCode, mProcessStats);
3134                 checkTime(startTime, "startProcess: done, added package to proc");
3135                 return app;
3136             }
3137
3138             // An application record is attached to a previous process,
3139             // clean it up now.
3140             if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3141             checkTime(startTime, "startProcess: bad proc running, killing");
3142             killProcessGroup(app.info.uid, app.pid);
3143             handleAppDiedLocked(app, true, true);
3144             checkTime(startTime, "startProcess: done killing old proc");
3145         }
3146
3147         String hostingNameStr = hostingName != null
3148                 ? hostingName.flattenToShortString() : null;
3149
3150         if (app == null) {
3151             checkTime(startTime, "startProcess: creating new process record");
3152             app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3153             if (app == null) {
3154                 Slog.w(TAG, "Failed making new process record for "
3155                         + processName + "/" + info.uid + " isolated=" + isolated);
3156                 return null;
3157             }
3158             app.crashHandler = crashHandler;
3159             checkTime(startTime, "startProcess: done creating new process record");
3160         } else {
3161             // If this is a new package in the process, add the package to the list
3162             app.addPackage(info.packageName, info.versionCode, mProcessStats);
3163             checkTime(startTime, "startProcess: added package to existing proc");
3164         }
3165
3166         // If the system is not ready yet, then hold off on starting this
3167         // process until it is.
3168         if (!mProcessesReady
3169                 && !isAllowedWhileBooting(info)
3170                 && !allowWhileBooting) {
3171             if (!mProcessesOnHold.contains(app)) {
3172                 mProcessesOnHold.add(app);
3173             }
3174             if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3175                     "System not ready, putting on hold: " + app);
3176             checkTime(startTime, "startProcess: returning with proc on hold");
3177             return app;
3178         }
3179
3180         checkTime(startTime, "startProcess: stepping in to startProcess");
3181         startProcessLocked(
3182                 app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3183         checkTime(startTime, "startProcess: done starting proc!");
3184         return (app.pid != 0) ? app : null;
3185     }
3186
3187     boolean isAllowedWhileBooting(ApplicationInfo ai) {
3188         return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3189     }
3190
3191     private final void startProcessLocked(ProcessRecord app,
3192             String hostingType, String hostingNameStr) {
3193         startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3194                 null /* entryPoint */, null /* entryPointArgs */);
3195     }
3196
3197     private final void startProcessLocked(ProcessRecord app, String hostingType,
3198             String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3199         long startTime = SystemClock.elapsedRealtime();
3200         if (app.pid > 0 && app.pid != MY_PID) {
3201             checkTime(startTime, "startProcess: removing from pids map");
3202             synchronized (mPidsSelfLocked) {
3203                 mPidsSelfLocked.remove(app.pid);
3204                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3205             }
3206             checkTime(startTime, "startProcess: done removing from pids map");
3207             app.setPid(0);
3208         }
3209
3210         if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3211                 "startProcessLocked removing on hold: " + app);
3212         mProcessesOnHold.remove(app);
3213
3214         checkTime(startTime, "startProcess: starting to update cpu stats");
3215         updateCpuStats();
3216         checkTime(startTime, "startProcess: done updating cpu stats");
3217
3218         try {
3219             try {
3220                 if (AppGlobals.getPackageManager().isPackageFrozen(app.info.packageName)) {
3221                     // This is caught below as if we had failed to fork zygote
3222                     throw new RuntimeException("Package " + app.info.packageName + " is frozen!");
3223                 }
3224             } catch (RemoteException e) {
3225                 throw e.rethrowAsRuntimeException();
3226             }
3227
3228             int uid = app.uid;
3229             int[] gids = null;
3230             int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3231             if (!app.isolated) {
3232                 int[] permGids = null;
3233                 try {
3234                     checkTime(startTime, "startProcess: getting gids from package manager");
3235                     final IPackageManager pm = AppGlobals.getPackageManager();
3236                     permGids = pm.getPackageGids(app.info.packageName, app.userId);
3237                     MountServiceInternal mountServiceInternal = LocalServices.getService(
3238                             MountServiceInternal.class);
3239                     mountExternal = mountServiceInternal.getExternalStorageMountMode(uid,
3240                             app.info.packageName);
3241                 } catch (RemoteException e) {
3242                     throw e.rethrowAsRuntimeException();
3243                 }
3244
3245                 /*
3246                  * Add shared application and profile GIDs so applications can share some
3247                  * resources like shared libraries and access user-wide resources
3248                  */
3249                 if (ArrayUtils.isEmpty(permGids)) {
3250                     gids = new int[2];
3251                 } else {
3252                     gids = new int[permGids.length + 2];
3253                     System.arraycopy(permGids, 0, gids, 2, permGids.length);
3254                 }
3255                 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3256                 gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3257             }
3258             checkTime(startTime, "startProcess: building args");
3259             if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3260                 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3261                         && mTopComponent != null
3262                         && app.processName.equals(mTopComponent.getPackageName())) {
3263                     uid = 0;
3264                 }
3265                 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3266                         && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3267                     uid = 0;
3268                 }
3269             }
3270             int debugFlags = 0;
3271             if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3272                 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3273                 // Also turn on CheckJNI for debuggable apps. It's quite
3274                 // awkward to turn on otherwise.
3275                 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3276             }
3277             // Run the app in safe mode if its manifest requests so or the
3278             // system is booted in safe mode.
3279             if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3280                 mSafeMode == true) {
3281                 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3282             }
3283             if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3284                 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3285             }
3286             String jitDebugProperty = SystemProperties.get("debug.usejit");
3287             if ("true".equals(jitDebugProperty)) {
3288                 debugFlags |= Zygote.DEBUG_ENABLE_JIT;
3289             } else if (!"false".equals(jitDebugProperty)) {
3290                 // If we didn't force disable by setting false, defer to the dalvik vm options.
3291                 if ("true".equals(SystemProperties.get("dalvik.vm.usejit"))) {
3292                     debugFlags |= Zygote.DEBUG_ENABLE_JIT;
3293                 }
3294             }
3295             String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3296             if ("true".equals(genDebugInfoProperty)) {
3297                 debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3298             }
3299             if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3300                 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3301             }
3302             if ("1".equals(SystemProperties.get("debug.assert"))) {
3303                 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3304             }
3305
3306             String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3307             if (requiredAbi == null) {
3308                 requiredAbi = Build.SUPPORTED_ABIS[0];
3309             }
3310
3311             String instructionSet = null;
3312             if (app.info.primaryCpuAbi != null) {
3313                 instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3314             }
3315
3316             app.gids = gids;
3317             app.requiredAbi = requiredAbi;
3318             app.instructionSet = instructionSet;
3319
3320             // Start the process.  It will either succeed and return a result containing
3321             // the PID of the new process, or else throw a RuntimeException.
3322             boolean isActivityProcess = (entryPoint == null);
3323             if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3324             Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3325                     app.processName);
3326             checkTime(startTime, "startProcess: asking zygote to start proc");
3327             Process.ProcessStartResult startResult = Process.start(entryPoint,
3328                     app.processName, uid, uid, gids, debugFlags, mountExternal,
3329                     app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3330                     app.info.dataDir, entryPointArgs);
3331             checkTime(startTime, "startProcess: returned from zygote!");
3332             Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3333
3334             if (app.isolated) {
3335                 mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3336             }
3337             mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3338             checkTime(startTime, "startProcess: done updating battery stats");
3339
3340             EventLog.writeEvent(EventLogTags.AM_PROC_START,
3341                     UserHandle.getUserId(uid), startResult.pid, uid,
3342                     app.processName, hostingType,
3343                     hostingNameStr != null ? hostingNameStr : "");
3344
3345             if (app.persistent) {
3346                 Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3347             }
3348
3349             checkTime(startTime, "startProcess: building log message");
3350             StringBuilder buf = mStringBuilder;
3351             buf.setLength(0);
3352             buf.append("Start proc ");
3353             buf.append(startResult.pid);
3354             buf.append(':');
3355             buf.append(app.processName);
3356             buf.append('/');
3357             UserHandle.formatUid(buf, uid);
3358             if (!isActivityProcess) {
3359                 buf.append(" [");
3360                 buf.append(entryPoint);
3361                 buf.append("]");
3362             }
3363             buf.append(" for ");
3364             buf.append(hostingType);
3365             if (hostingNameStr != null) {
3366                 buf.append(" ");
3367                 buf.append(hostingNameStr);
3368             }
3369             Slog.i(TAG, buf.toString());
3370             app.setPid(startResult.pid);
3371             app.usingWrapper = startResult.usingWrapper;
3372             app.removed = false;
3373             app.killed = false;
3374             app.killedByAm = false;
3375             checkTime(startTime, "startProcess: starting to update pids map");
3376             synchronized (mPidsSelfLocked) {
3377                 this.mPidsSelfLocked.put(startResult.pid, app);
3378                 if (isActivityProcess) {
3379                     Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3380                     msg.obj = app;
3381                     mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3382                             ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3383                 }
3384             }
3385             checkTime(startTime, "startProcess: done updating pids map");
3386         } catch (RuntimeException e) {
3387             // XXX do better error recovery.
3388             app.setPid(0);
3389             mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3390             if (app.isolated) {
3391                 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3392             }
3393             Slog.e(TAG, "Failure starting process " + app.processName, e);
3394         }
3395     }
3396
3397     void updateUsageStats(ActivityRecord component, boolean resumed) {
3398         if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
3399                 "updateUsageStats: comp=" + component + "res=" + resumed);
3400         final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3401         if (resumed) {
3402             if (mUsageStatsService != null) {
3403                 mUsageStatsService.reportEvent(component.realActivity, component.userId,
3404                         UsageEvents.Event.MOVE_TO_FOREGROUND);
3405             }
3406             synchronized (stats) {
3407                 stats.noteActivityResumedLocked(component.app.uid);
3408             }
3409         } else {
3410             if (mUsageStatsService != null) {
3411                 mUsageStatsService.reportEvent(component.realActivity, component.userId,
3412                         UsageEvents.Event.MOVE_TO_BACKGROUND);
3413             }
3414             synchronized (stats) {
3415                 stats.noteActivityPausedLocked(component.app.uid);
3416             }
3417         }
3418     }
3419
3420     Intent getHomeIntent() {
3421         Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3422         intent.setComponent(mTopComponent);
3423         if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3424             intent.addCategory(Intent.CATEGORY_HOME);
3425         }
3426         return intent;
3427     }
3428
3429     boolean startHomeActivityLocked(int userId, String reason) {
3430         if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3431                 && mTopAction == null) {
3432             // We are running in factory test mode, but unable to find
3433             // the factory test app, so just sit around displaying the
3434             // error message and don't try to start anything.
3435             return false;
3436         }
3437         Intent intent = getHomeIntent();
3438         ActivityInfo aInfo =
3439             resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3440         if (aInfo != null) {
3441             intent.setComponent(new ComponentName(
3442                     aInfo.applicationInfo.packageName, aInfo.name));
3443             // Don't do this if the home app is currently being
3444             // instrumented.
3445             aInfo = new ActivityInfo(aInfo);
3446             aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3447             ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3448                     aInfo.applicationInfo.uid, true);
3449             if (app == null || app.instrumentationClass == null) {
3450                 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3451                 mStackSupervisor.startHomeActivity(intent, aInfo, reason);
3452             }
3453         }
3454
3455         return true;
3456     }
3457
3458     private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3459         ActivityInfo ai = null;
3460         ComponentName comp = intent.getComponent();
3461         try {
3462             if (comp != null) {
3463                 // Factory test.
3464                 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3465             } else {
3466                 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3467                         intent,
3468                         intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3469                         flags, userId);
3470
3471                 if (info != null) {
3472                     ai = info.activityInfo;
3473                 }
3474             }
3475         } catch (RemoteException e) {
3476             // ignore
3477         }
3478
3479         return ai;
3480     }
3481
3482     /**
3483      * Starts the "new version setup screen" if appropriate.
3484      */
3485     void startSetupActivityLocked() {
3486         // Only do this once per boot.
3487         if (mCheckedForSetup) {
3488             return;
3489         }
3490
3491         // We will show this screen if the current one is a different
3492         // version than the last one shown, and we are not running in
3493         // low-level factory test mode.
3494         final ContentResolver resolver = mContext.getContentResolver();
3495         if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3496                 Settings.Global.getInt(resolver,
3497                         Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3498             mCheckedForSetup = true;
3499
3500             // See if we should be showing the platform update setup UI.
3501             Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3502             List<ResolveInfo> ris = mContext.getPackageManager()
3503                     .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3504
3505             // We don't allow third party apps to replace this.
3506             ResolveInfo ri = null;
3507             for (int i=0; ris != null && i<ris.size(); i++) {
3508                 if ((ris.get(i).activityInfo.applicationInfo.flags
3509                         & ApplicationInfo.FLAG_SYSTEM) != 0) {
3510                     ri = ris.get(i);
3511                     break;
3512                 }
3513             }
3514
3515             if (ri != null) {
3516                 String vers = ri.activityInfo.metaData != null
3517                         ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3518                         : null;
3519                 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3520                     vers = ri.activityInfo.applicationInfo.metaData.getString(
3521                             Intent.METADATA_SETUP_VERSION);
3522                 }
3523                 String lastVers = Settings.Secure.getString(
3524                         resolver, Settings.Secure.LAST_SETUP_SHOWN);
3525                 if (vers != null && !vers.equals(lastVers)) {
3526                     intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3527                     intent.setComponent(new ComponentName(
3528                             ri.activityInfo.packageName, ri.activityInfo.name));
3529                     mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3530                             null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, false,
3531                             null, null, null);
3532                 }
3533             }
3534         }
3535     }
3536
3537     CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3538         return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3539     }
3540
3541     void enforceNotIsolatedCaller(String caller) {
3542         if (UserHandle.isIsolated(Binder.getCallingUid())) {
3543             throw new SecurityException("Isolated process not allowed to call " + caller);
3544         }
3545     }
3546
3547     void enforceShellRestriction(String restriction, int userHandle) {
3548         if (Binder.getCallingUid() == Process.SHELL_UID) {
3549             if (userHandle < 0
3550                     || mUserManager.hasUserRestriction(restriction, userHandle)) {
3551                 throw new SecurityException("Shell does not have permission to access user "
3552                         + userHandle);
3553             }
3554         }
3555     }
3556
3557     @Override
3558     public int getFrontActivityScreenCompatMode() {
3559         enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3560         synchronized (this) {
3561             return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3562         }
3563     }
3564
3565     @Override
3566     public void setFrontActivityScreenCompatMode(int mode) {
3567         enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3568                 "setFrontActivityScreenCompatMode");
3569         synchronized (this) {
3570             mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3571         }
3572     }
3573
3574     @Override
3575     public int getPackageScreenCompatMode(String packageName) {
3576         enforceNotIsolatedCaller("getPackageScreenCompatMode");
3577         synchronized (this) {
3578             return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3579         }
3580     }
3581
3582     @Override
3583     public void setPackageScreenCompatMode(String packageName, int mode) {
3584         enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3585                 "setPackageScreenCompatMode");
3586         synchronized (this) {
3587             mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3588         }
3589     }
3590
3591     @Override
3592     public boolean getPackageAskScreenCompat(String packageName) {
3593         enforceNotIsolatedCaller("getPackageAskScreenCompat");
3594         synchronized (this) {
3595             return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3596         }
3597     }
3598
3599     @Override
3600     public void setPackageAskScreenCompat(String packageName, boolean ask) {
3601         enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3602                 "setPackageAskScreenCompat");
3603         synchronized (this) {
3604             mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3605         }
3606     }
3607
3608     private boolean hasUsageStatsPermission(String callingPackage) {
3609         final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
3610                 Binder.getCallingUid(), callingPackage);
3611         if (mode == AppOpsManager.MODE_DEFAULT) {
3612             return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
3613                     == PackageManager.PERMISSION_GRANTED;
3614         }
3615         return mode == AppOpsManager.MODE_ALLOWED;
3616     }
3617
3618     @Override
3619     public int getPackageProcessState(String packageName, String callingPackage) {
3620         if (!hasUsageStatsPermission(callingPackage)) {
3621             enforceCallingPermission(android.Manifest.permission.GET_PACKAGE_IMPORTANCE,
3622                     "getPackageProcessState");
3623         }
3624
3625         int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
3626         synchronized (this) {
3627             for (int i=mLruProcesses.size()-1; i>=0; i--) {
3628                 final ProcessRecord proc = mLruProcesses.get(i);
3629                 if (procState == ActivityManager.PROCESS_STATE_NONEXISTENT
3630                         || procState > proc.setProcState) {
3631                     boolean found = false;
3632                     for (int j=proc.pkgList.size()-1; j>=0 && !found; j--) {
3633                         if (proc.pkgList.keyAt(j).equals(packageName)) {
3634                             procState = proc.setProcState;
3635                             found = true;
3636                         }
3637                     }
3638                     if (proc.pkgDeps != null && !found) {
3639                         for (int j=proc.pkgDeps.size()-1; j>=0; j--) {
3640                             if (proc.pkgDeps.valueAt(j).equals(packageName)) {
3641                                 procState = proc.setProcState;
3642                                 break;
3643                             }
3644                         }
3645                     }
3646                 }
3647             }
3648         }
3649         return procState;
3650     }
3651
3652     @Override
3653     public boolean setProcessMemoryTrimLevel(String process, int userId, int level) {
3654         synchronized (this) {
3655             final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
3656             if (app == null) {
3657                 return false;
3658             }
3659             if (app.trimMemoryLevel < level && app.thread != null &&
3660                     (level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
3661                             app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND)) {
3662                 try {
3663                     app.thread.scheduleTrimMemory(level);
3664                     app.trimMemoryLevel = level;
3665                     return true;
3666                 } catch (RemoteException e) {
3667                     // Fallthrough to failure case.
3668                 }
3669             }
3670         }
3671         return false;
3672     }
3673
3674     private void dispatchProcessesChanged() {
3675         int N;
3676         synchronized (this) {
3677             N = mPendingProcessChanges.size();
3678             if (mActiveProcessChanges.length < N) {
3679                 mActiveProcessChanges = new ProcessChangeItem[N];
3680             }
3681             mPendingProcessChanges.toArray(mActiveProcessChanges);
3682             mPendingProcessChanges.clear();
3683             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
3684                     "*** Delivering " + N + " process changes");
3685         }
3686
3687         int i = mProcessObservers.beginBroadcast();
3688         while (i > 0) {
3689             i--;
3690             final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3691             if (observer != null) {
3692                 try {
3693                     for (int j=0; j<N; j++) {
3694                         ProcessChangeItem item = mActiveProcessChanges[j];
3695                         if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3696                             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
3697                                     "ACTIVITIES CHANGED pid=" + item.pid + " uid="
3698                                     + item.uid + ": " + item.foregroundActivities);
3699                             observer.onForegroundActivitiesChanged(item.pid, item.uid,
3700                                     item.foregroundActivities);
3701                         }
3702                         if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3703                             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
3704                                     "PROCSTATE CHANGED pid=" + item.pid + " uid=" + item.uid
3705                                     + ": " + item.processState);
3706                             observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3707                         }
3708                     }
3709                 } catch (RemoteException e) {
3710                 }
3711             }
3712         }
3713         mProcessObservers.finishBroadcast();
3714
3715         synchronized (this) {
3716             for (int j=0; j<N; j++) {
3717                 mAvailProcessChanges.add(mActiveProcessChanges[j]);
3718             }
3719         }
3720     }
3721
3722     private void dispatchProcessDied(int pid, int uid) {
3723         int i = mProcessObservers.beginBroadcast();
3724         while (i > 0) {
3725             i--;
3726             final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3727             if (observer != null) {
3728                 try {
3729                     observer.onProcessDied(pid, uid);
3730                 } catch (RemoteException e) {
3731                 }
3732             }
3733         }
3734         mProcessObservers.finishBroadcast();
3735     }
3736
3737     private void dispatchUidsChanged() {
3738         int N;
3739         synchronized (this) {
3740             N = mPendingUidChanges.size();
3741             if (mActiveUidChanges.length < N) {
3742                 mActiveUidChanges = new UidRecord.ChangeItem[N];
3743             }
3744             for (int i=0; i<N; i++) {
3745                 final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
3746                 mActiveUidChanges[i] = change;
3747                 change.uidRecord.pendingChange = null;
3748                 change.uidRecord = null;
3749             }
3750             mPendingUidChanges.clear();
3751             if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
3752                     "*** Delivering " + N + " uid changes");
3753         }
3754
3755         if (mLocalPowerManager != null) {
3756             for (int j=0; j<N; j++) {
3757                 UidRecord.ChangeItem item = mActiveUidChanges[j];
3758                 if (item.gone) {
3759                     mLocalPowerManager.uidGone(item.uid);
3760                 } else {
3761                     mLocalPowerManager.updateUidProcState(item.uid, item.processState);
3762                 }
3763             }
3764         }
3765
3766         int i = mUidObservers.beginBroadcast();
3767         while (i > 0) {
3768             i--;
3769             final IUidObserver observer = mUidObservers.getBroadcastItem(i);
3770             if (observer != null) {
3771                 try {
3772                     for (int j=0; j<N; j++) {
3773                         UidRecord.ChangeItem item = mActiveUidChanges[j];
3774                         if (item.gone) {
3775                             if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
3776                                     "UID gone uid=" + item.uid);
3777                             observer.onUidGone(item.uid);
3778                         } else {
3779                             if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
3780                                     "UID CHANGED uid=" + item.uid
3781                                     + ": " + item.processState);
3782                             observer.onUidStateChanged(item.uid, item.processState);
3783                         }
3784                     }
3785                 } catch (RemoteException e) {
3786                 }
3787             }
3788         }
3789         mUidObservers.finishBroadcast();
3790
3791         synchronized (this) {
3792             for (int j=0; j<N; j++) {
3793                 mAvailUidChanges.add(mActiveUidChanges[j]);
3794             }
3795         }
3796     }
3797
3798     @Override
3799     public final int startActivity(IApplicationThread caller, String callingPackage,
3800             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3801             int startFlags, ProfilerInfo profilerInfo, Bundle options) {
3802         return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3803             resultWho, requestCode, startFlags, profilerInfo, options,
3804             UserHandle.getCallingUserId());
3805     }
3806
3807     @Override
3808     public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3809             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3810             int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3811         enforceNotIsolatedCaller("startActivity");
3812         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3813                 false, ALLOW_FULL_ONLY, "startActivity", null);
3814         // TODO: Switch to user app stacks here.
3815         return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3816                 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3817                 profilerInfo, null, null, options, false, userId, null, null);
3818     }
3819
3820     @Override
3821     public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
3822             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3823             int startFlags, ProfilerInfo profilerInfo, Bundle options, boolean ignoreTargetSecurity,
3824             int userId) {
3825
3826         // This is very dangerous -- it allows you to perform a start activity (including
3827         // permission grants) as any app that may launch one of your own activities.  So
3828         // we will only allow this to be done from activities that are part of the core framework,
3829         // and then only when they are running as the system.
3830         final ActivityRecord sourceRecord;
3831         final int targetUid;
3832         final String targetPackage;
3833         synchronized (this) {
3834             if (resultTo == null) {
3835                 throw new SecurityException("Must be called from an activity");
3836             }
3837             sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
3838             if (sourceRecord == null) {
3839                 throw new SecurityException("Called with bad activity token: " + resultTo);
3840             }
3841             if (!sourceRecord.info.packageName.equals("android")) {
3842                 throw new SecurityException(
3843                         "Must be called from an activity that is declared in the android package");
3844             }
3845             if (sourceRecord.app == null) {
3846                 throw new SecurityException("Called without a process attached to activity");
3847             }
3848             if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
3849                 // This is still okay, as long as this activity is running under the
3850                 // uid of the original calling activity.
3851                 if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
3852                     throw new SecurityException(
3853                             "Calling activity in uid " + sourceRecord.app.uid
3854                                     + " must be system uid or original calling uid "
3855                                     + sourceRecord.launchedFromUid);
3856                 }
3857             }
3858             if (ignoreTargetSecurity) {
3859                 if (intent.getComponent() == null) {
3860                     throw new SecurityException(
3861                             "Component must be specified with ignoreTargetSecurity");
3862                 }
3863                 if (intent.getSelector() != null) {
3864                     throw new SecurityException(
3865                             "Selector not allowed with ignoreTargetSecurity");
3866                 }
3867             }
3868             targetUid = sourceRecord.launchedFromUid;
3869             targetPackage = sourceRecord.launchedFromPackage;
3870         }
3871
3872         if (userId == UserHandle.USER_NULL) {
3873             userId = UserHandle.getUserId(sourceRecord.app.uid);
3874         }
3875
3876         // TODO: Switch to user app stacks here.
3877         try {
3878             int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent,
3879                     resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
3880                     null, null, options, ignoreTargetSecurity, userId, null, null);
3881             return ret;
3882         } catch (SecurityException e) {
3883             // XXX need to figure out how to propagate to original app.
3884             // A SecurityException here is generally actually a fault of the original
3885             // calling activity (such as a fairly granting permissions), so propagate it
3886             // back to them.
3887             /*
3888             StringBuilder msg = new StringBuilder();
3889             msg.append("While launching");
3890             msg.append(intent.toString());
3891             msg.append(": ");
3892             msg.append(e.getMessage());
3893             */
3894             throw e;
3895         }
3896     }
3897
3898     @Override
3899     public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3900             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3901             int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3902         enforceNotIsolatedCaller("startActivityAndWait");
3903         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3904                 false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
3905         WaitResult res = new WaitResult();
3906         // TODO: Switch to user app stacks here.
3907         mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3908                 null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
3909                 options, false, userId, null, null);
3910         return res;
3911     }
3912
3913     @Override
3914     public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3915             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3916             int startFlags, Configuration config, Bundle options, int userId) {
3917         enforceNotIsolatedCaller("startActivityWithConfig");
3918         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3919                 false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
3920         // TODO: Switch to user app stacks here.
3921         int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3922                 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3923                 null, null, config, options, false, userId, null, null);
3924         return ret;
3925     }
3926
3927     @Override
3928     public int startActivityIntentSender(IApplicationThread caller, IntentSender intent,
3929             Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho,
3930             int requestCode, int flagsMask, int flagsValues, Bundle options)
3931             throws TransactionTooLargeException {
3932         enforceNotIsolatedCaller("startActivityIntentSender");
3933         // Refuse possible leaked file descriptors
3934         if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3935             throw new IllegalArgumentException("File descriptors passed in Intent");
3936         }
3937
3938         IIntentSender sender = intent.getTarget();
3939         if (!(sender instanceof PendingIntentRecord)) {
3940             throw new IllegalArgumentException("Bad PendingIntent object");
3941         }
3942
3943         PendingIntentRecord pir = (PendingIntentRecord)sender;
3944
3945         synchronized (this) {
3946             // If this is coming from the currently resumed activity, it is
3947             // effectively saying that app switches are allowed at this point.
3948             final ActivityStack stack = getFocusedStack();
3949             if (stack.mResumedActivity != null &&
3950                     stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3951                 mAppSwitchesAllowedTime = 0;
3952             }
3953         }
3954         int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3955                 resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3956         return ret;
3957     }
3958
3959     @Override
3960     public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3961             Intent intent, String resolvedType, IVoiceInteractionSession session,
3962             IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
3963             Bundle options, int userId) {
3964         if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3965                 != PackageManager.PERMISSION_GRANTED) {
3966             String msg = "Permission Denial: startVoiceActivity() from pid="
3967                     + Binder.getCallingPid()
3968                     + ", uid=" + Binder.getCallingUid()
3969                     + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3970             Slog.w(TAG, msg);
3971             throw new SecurityException(msg);
3972         }
3973         if (session == null || interactor == null) {
3974             throw new NullPointerException("null session or interactor");
3975         }
3976         userId = handleIncomingUser(callingPid, callingUid, userId,
3977                 false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
3978         // TODO: Switch to user app stacks here.
3979         return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3980                 resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
3981                 null, options, false, userId, null, null);
3982     }
3983
3984     @Override
3985     public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
3986         synchronized (this) {
3987             if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
3988                 if (keepAwake) {
3989                     mVoiceWakeLock.acquire();
3990                 } else {
3991                     mVoiceWakeLock.release();
3992                 }
3993             }
3994         }
3995     }
3996
3997     @Override
3998     public boolean startNextMatchingActivity(IBinder callingActivity,
3999             Intent intent, Bundle options) {
4000         // Refuse possible leaked file descriptors
4001         if (intent != null && intent.hasFileDescriptors() == true) {
4002             throw new IllegalArgumentException("File descriptors passed in Intent");
4003         }
4004
4005         synchronized (this) {
4006             final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4007             if (r == null) {
4008                 ActivityOptions.abort(options);
4009                 return false;
4010             }
4011             if (r.app == null || r.app.thread == null) {
4012                 // The caller is not running...  d'oh!
4013                 ActivityOptions.abort(options);
4014                 return false;
4015             }
4016             intent = new Intent(intent);
4017             // The caller is not allowed to change the data.
4018             intent.setDataAndType(r.intent.getData(), r.intent.getType());
4019             // And we are resetting to find the next component...
4020             intent.setComponent(null);
4021
4022             final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4023
4024             ActivityInfo aInfo = null;
4025             try {
4026                 List<ResolveInfo> resolves =
4027                     AppGlobals.getPackageManager().queryIntentActivities(
4028                             intent, r.resolvedType,
4029                             PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4030                             UserHandle.getCallingUserId());
4031
4032                 // Look for the original activity in the list...
4033                 final int N = resolves != null ? resolves.size() : 0;
4034                 for (int i=0; i<N; i++) {
4035                     ResolveInfo rInfo = resolves.get(i);
4036                     if (rInfo.activityInfo.packageName.equals(r.packageName)
4037                             && rInfo.activityInfo.name.equals(r.info.name)) {
4038                         // We found the current one...  the next matching is
4039                         // after it.
4040                         i++;
4041                         if (i<N) {
4042                             aInfo = resolves.get(i).activityInfo;
4043                         }
4044                         if (debug) {
4045                             Slog.v(TAG, "Next matching activity: found current " + r.packageName
4046                                     + "/" + r.info.name);
4047                             Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
4048                                     + "/" + aInfo.name);
4049                         }
4050                         break;
4051                     }
4052                 }
4053             } catch (RemoteException e) {
4054             }
4055
4056             if (aInfo == null) {
4057                 // Nobody who is next!
4058                 ActivityOptions.abort(options);
4059                 if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4060                 return false;
4061             }
4062
4063             intent.setComponent(new ComponentName(
4064                     aInfo.applicationInfo.packageName, aInfo.name));
4065             intent.setFlags(intent.getFlags()&~(
4066                     Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4067                     Intent.FLAG_ACTIVITY_CLEAR_TOP|
4068                     Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4069                     Intent.FLAG_ACTIVITY_NEW_TASK));
4070
4071             // Okay now we need to start the new activity, replacing the
4072             // currently running activity.  This is a little tricky because
4073             // we want to start the new one as if the current one is finished,
4074             // but not finish the current one first so that there is no flicker.
4075             // And thus...
4076             final boolean wasFinishing = r.finishing;
4077             r.finishing = true;
4078
4079             // Propagate reply information over to the new activity.
4080             final ActivityRecord resultTo = r.resultTo;
4081             final String resultWho = r.resultWho;
4082             final int requestCode = r.requestCode;
4083             r.resultTo = null;
4084             if (resultTo != null) {
4085                 resultTo.removeResultsLocked(r, resultWho, requestCode);
4086             }
4087
4088             final long origId = Binder.clearCallingIdentity();
4089             int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
4090                     r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
4091                     resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage,
4092                     -1, r.launchedFromUid, 0, options, false, false, null, null, null);
4093             Binder.restoreCallingIdentity(origId);
4094
4095             r.finishing = wasFinishing;
4096             if (res != ActivityManager.START_SUCCESS) {
4097                 return false;
4098             }
4099             return true;
4100         }
4101     }
4102
4103     @Override
4104     public final int startActivityFromRecents(int taskId, Bundle options) {
4105         if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4106             String msg = "Permission Denial: startActivityFromRecents called without " +
4107                     START_TASKS_FROM_RECENTS;
4108             Slog.w(TAG, msg);
4109             throw new SecurityException(msg);
4110         }
4111         return startActivityFromRecentsInner(taskId, options);
4112     }
4113
4114     final int startActivityFromRecentsInner(int taskId, Bundle options) {
4115         final TaskRecord task;
4116         final int callingUid;
4117         final String callingPackage;
4118         final Intent intent;
4119         final int userId;
4120         synchronized (this) {
4121             task = mStackSupervisor.anyTaskForIdLocked(taskId);
4122             if (task == null) {
4123                 throw new IllegalArgumentException("Task " + taskId + " not found.");
4124             }
4125             if (task.getRootActivity() != null) {
4126                 moveTaskToFrontLocked(task.taskId, 0, null);
4127                 return ActivityManager.START_TASK_TO_FRONT;
4128             }
4129             callingUid = task.mCallingUid;
4130             callingPackage = task.mCallingPackage;
4131             intent = task.intent;
4132             intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
4133             userId = task.userId;
4134         }
4135         return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
4136                 options, userId, null, task);
4137     }
4138
4139     final int startActivityInPackage(int uid, String callingPackage,
4140             Intent intent, String resolvedType, IBinder resultTo,
4141             String resultWho, int requestCode, int startFlags, Bundle options, int userId,
4142             IActivityContainer container, TaskRecord inTask) {
4143
4144         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
4145                 false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4146
4147         // TODO: Switch to user app stacks here.
4148         int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent,
4149                 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4150                 null, null, null, options, false, userId, container, inTask);
4151         return ret;
4152     }
4153
4154     @Override
4155     public final int startActivities(IApplicationThread caller, String callingPackage,
4156             Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
4157             int userId) {
4158         enforceNotIsolatedCaller("startActivities");
4159         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
4160                 false, ALLOW_FULL_ONLY, "startActivity", null);
4161         // TODO: Switch to user app stacks here.
4162         int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
4163                 resolvedTypes, resultTo, options, userId);
4164         return ret;
4165     }
4166
4167     final int startActivitiesInPackage(int uid, String callingPackage,
4168             Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4169             Bundle options, int userId) {
4170
4171         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
4172                 false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4173         // TODO: Switch to user app stacks here.
4174         int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4175                 resultTo, options, userId);
4176         return ret;
4177     }
4178
4179     @Override
4180     public void reportActivityFullyDrawn(IBinder token) {
4181         synchronized (this) {
4182             ActivityRecord r = ActivityRecord.isInStackLocked(token);
4183             if (r == null) {
4184                 return;
4185             }
4186             r.reportFullyDrawnLocked();
4187         }
4188     }
4189
4190     @Override
4191     public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4192         synchronized (this) {
4193             ActivityRecord r = ActivityRecord.isInStackLocked(token);
4194             if (r == null) {
4195                 return;
4196             }
4197             if (r.task != null && r.task.mResizeable) {
4198                 // Fixed screen orientation isn't supported with resizeable activities.
4199                 return;
4200             }
4201             final long origId = Binder.clearCallingIdentity();
4202             mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4203             Configuration config = mWindowManager.updateOrientationFromAppTokens(
4204                     mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4205             if (config != null) {
4206                 r.frozenBeforeDestroy = true;
4207                 if (!updateConfigurationLocked(config, r, false, false)) {
4208                     mStackSupervisor.resumeTopActivitiesLocked();
4209                 }
4210             }
4211             Binder.restoreCallingIdentity(origId);
4212         }
4213     }
4214
4215     @Override
4216     public int getRequestedOrientation(IBinder token) {
4217         synchronized (this) {
4218             ActivityRecord r = ActivityRecord.isInStackLocked(token);
4219             if (r == null) {
4220                 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4221             }
4222             return mWindowManager.getAppOrientation(r.appToken);
4223         }
4224     }
4225
4226     /**
4227      * This is the internal entry point for handling Activity.finish().
4228      *
4229      * @param token The Binder token referencing the Activity we want to finish.
4230      * @param resultCode Result code, if any, from this Activity.
4231      * @param resultData Result data (Intent), if any, from this Activity.
4232      * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
4233      *            the root Activity in the task.
4234      *
4235      * @return Returns true if the activity successfully finished, or false if it is still running.
4236      */
4237     @Override
4238     public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4239             boolean finishTask) {
4240         // Refuse possible leaked file descriptors
4241         if (resultData != null && resultData.hasFileDescriptors() == true) {
4242             throw new IllegalArgumentException("File descriptors passed in Intent");
4243         }
4244
4245         synchronized(this) {
4246             ActivityRecord r = ActivityRecord.isInStackLocked(token);
4247             if (r == null) {
4248                 return true;
4249             }
4250             // Keep track of the root activity of the task before we finish it
4251             TaskRecord tr = r.task;
4252             ActivityRecord rootR = tr.getRootActivity();
4253             if (rootR == null) {
4254                 Slog.w(TAG, "Finishing task with all activities already finished");
4255             }
4256             // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
4257             // finish.
4258             if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
4259                     mStackSupervisor.isLastLockedTask(tr)) {
4260                 Slog.i(TAG, "Not finishing task in lock task mode");
4261                 mStackSupervisor.showLockTaskToast();
4262                 return false;
4263             }
4264             if (mController != null) {
4265                 // Find the first activity that is not finishing.
4266                 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4267                 if (next != null) {
4268                     // ask watcher if this is allowed
4269                     boolean resumeOK = true;
4270                     try {
4271                         resumeOK = mController.activityResuming(next.packageName);
4272                     } catch (RemoteException e) {
4273                         mController = null;
4274                         Watchdog.getInstance().setActivityController(null);
4275                     }
4276
4277                     if (!resumeOK) {
4278                         Slog.i(TAG, "Not finishing activity because controller resumed");
4279                         return false;
4280                     }
4281                 }
4282             }
4283             final long origId = Binder.clearCallingIdentity();
4284             try {
4285                 boolean res;
4286                 if (finishTask && r == rootR) {
4287                     // If requested, remove the task that is associated to this activity only if it
4288                     // was the root activity in the task. The result code and data is ignored
4289                     // because we don't support returning them across task boundaries.
4290                     res = removeTaskByIdLocked(tr.taskId, false);
4291                     if (!res) {
4292                         Slog.i(TAG, "Removing task failed to finish activity");
4293                     }
4294                 } else {
4295                     res = tr.stack.requestFinishActivityLocked(token, resultCode,
4296                             resultData, "app-request", true);
4297                     if (!res) {
4298                         Slog.i(TAG, "Failed to finish by app-request");
4299                     }
4300                 }
4301                 return res;
4302             } finally {
4303                 Binder.restoreCallingIdentity(origId);
4304             }
4305         }
4306     }
4307
4308     @Override
4309     public final void finishHeavyWeightApp() {
4310         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4311                 != PackageManager.PERMISSION_GRANTED) {
4312             String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4313                     + Binder.getCallingPid()
4314                     + ", uid=" + Binder.getCallingUid()
4315                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4316             Slog.w(TAG, msg);
4317             throw new SecurityException(msg);
4318         }
4319
4320         synchronized(this) {
4321             if (mHeavyWeightProcess == null) {
4322                 return;
4323             }
4324
4325             ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
4326             for (int i = 0; i < activities.size(); i++) {
4327                 ActivityRecord r = activities.get(i);
4328                 if (!r.finishing && r.isInStackLocked()) {
4329                     r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4330                             null, "finish-heavy", true);
4331                 }
4332             }
4333
4334             mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4335                     mHeavyWeightProcess.userId, 0));
4336             mHeavyWeightProcess = null;
4337         }
4338     }
4339
4340     @Override
4341     public void crashApplication(int uid, int initialPid, String packageName,
4342             String message) {
4343         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4344                 != PackageManager.PERMISSION_GRANTED) {
4345             String msg = "Permission Denial: crashApplication() from pid="
4346                     + Binder.getCallingPid()
4347                     + ", uid=" + Binder.getCallingUid()
4348                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4349             Slog.w(TAG, msg);
4350             throw new SecurityException(msg);
4351         }
4352
4353         synchronized(this) {
4354             ProcessRecord proc = null;
4355
4356             // Figure out which process to kill.  We don't trust that initialPid
4357             // still has any relation to current pids, so must scan through the
4358             // list.
4359             synchronized (mPidsSelfLocked) {
4360                 for (int i=0; i<mPidsSelfLocked.size(); i++) {
4361                     ProcessRecord p = mPidsSelfLocked.valueAt(i);
4362                     if (p.uid != uid) {
4363                         continue;
4364                     }
4365                     if (p.pid == initialPid) {
4366                         proc = p;
4367                         break;
4368                     }
4369                     if (p.pkgList.containsKey(packageName)) {
4370                         proc = p;
4371                     }
4372                 }
4373             }
4374
4375             if (proc == null) {
4376                 Slog.w(TAG, "crashApplication: nothing for uid=" + uid
4377                         + " initialPid=" + initialPid
4378                         + " packageName=" + packageName);
4379                 return;
4380             }
4381
4382             if (proc.thread != null) {
4383                 if (proc.pid == Process.myPid()) {
4384                     Log.w(TAG, "crashApplication: trying to crash self!");
4385                     return;
4386                 }
4387                 long ident = Binder.clearCallingIdentity();
4388                 try {
4389                     proc.thread.scheduleCrash(message);
4390                 } catch (RemoteException e) {
4391                 }
4392                 Binder.restoreCallingIdentity(ident);
4393             }
4394         }
4395     }
4396
4397     @Override
4398     public final void finishSubActivity(IBinder token, String resultWho,
4399             int requestCode) {
4400         synchronized(this) {
4401             final long origId = Binder.clearCallingIdentity();
4402             ActivityRecord r = ActivityRecord.isInStackLocked(token);
4403             if (r != null) {
4404                 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4405             }
4406             Binder.restoreCallingIdentity(origId);
4407         }
4408     }
4409
4410     @Override
4411     public boolean finishActivityAffinity(IBinder token) {
4412         synchronized(this) {
4413             final long origId = Binder.clearCallingIdentity();
4414             try {
4415                 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4416                 if (r == null) {
4417                     return false;
4418                 }
4419
4420                 // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
4421                 // can finish.
4422                 final TaskRecord task = r.task;
4423                 if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
4424                         mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
4425                     mStackSupervisor.showLockTaskToast();
4426                     return false;
4427                 }
4428                 return task.stack.finishActivityAffinityLocked(r);
4429             } finally {
4430                 Binder.restoreCallingIdentity(origId);
4431             }
4432         }
4433     }
4434
4435     @Override
4436     public void finishVoiceTask(IVoiceInteractionSession session) {
4437         synchronized(this) {
4438             final long origId = Binder.clearCallingIdentity();
4439             try {
4440                 mStackSupervisor.finishVoiceTask(session);
4441             } finally {
4442                 Binder.restoreCallingIdentity(origId);
4443             }
4444         }
4445
4446     }
4447
4448     @Override
4449     public boolean releaseActivityInstance(IBinder token) {
4450         synchronized(this) {
4451             final long origId = Binder.clearCallingIdentity();
4452             try {
4453                 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4454                 if (r == null) {
4455                     return false;
4456                 }
4457                 return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4458             } finally {
4459                 Binder.restoreCallingIdentity(origId);
4460             }
4461         }
4462     }
4463
4464     @Override
4465     public void releaseSomeActivities(IApplicationThread appInt) {
4466         synchronized(this) {
4467             final long origId = Binder.clearCallingIdentity();
4468             try {
4469                 ProcessRecord app = getRecordForAppLocked(appInt);
4470                 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4471             } finally {
4472                 Binder.restoreCallingIdentity(origId);
4473             }
4474         }
4475     }
4476
4477     @Override
4478     public boolean willActivityBeVisible(IBinder token) {
4479         synchronized(this) {
4480             ActivityStack stack = ActivityRecord.getStackLocked(token);
4481             if (stack != null) {
4482                 return stack.willActivityBeVisibleLocked(token);
4483             }
4484             return false;
4485         }
4486     }
4487
4488     @Override
4489     public void overridePendingTransition(IBinder token, String packageName,
4490             int enterAnim, int exitAnim) {
4491         synchronized(this) {
4492             ActivityRecord self = ActivityRecord.isInStackLocked(token);
4493             if (self == null) {
4494                 return;
4495             }
4496
4497             final long origId = Binder.clearCallingIdentity();
4498
4499             if (self.state == ActivityState.RESUMED
4500                     || self.state == ActivityState.PAUSING) {
4501                 mWindowManager.overridePendingAppTransition(packageName,
4502                         enterAnim, exitAnim, null);
4503             }
4504
4505             Binder.restoreCallingIdentity(origId);
4506         }
4507     }
4508
4509     /**
4510      * Main function for removing an existing process from the activity manager
4511      * as a result of that process going away.  Clears out all connections
4512      * to the process.
4513      */
4514     private final void handleAppDiedLocked(ProcessRecord app,
4515             boolean restarting, boolean allowRestart) {
4516         int pid = app.pid;
4517         boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4518         if (!kept && !restarting) {
4519             removeLruProcessLocked(app);
4520             if (pid > 0) {
4521                 ProcessList.remove(pid);
4522             }
4523         }
4524
4525         if (mProfileProc == app) {
4526             clearProfilerLocked();
4527         }
4528
4529         // Remove this application's activities from active lists.
4530         boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4531
4532         app.activities.clear();
4533
4534         if (app.instrumentationClass != null) {
4535             Slog.w(TAG, "Crash of app " + app.processName
4536                   + " running instrumentation " + app.instrumentationClass);
4537             Bundle info = new Bundle();
4538             info.putString("shortMsg", "Process crashed.");
4539             finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4540         }
4541
4542         if (!restarting && hasVisibleActivities && !mStackSupervisor.resumeTopActivitiesLocked()) {
4543             // If there was nothing to resume, and we are not already
4544             // restarting this process, but there is a visible activity that
4545             // is hosted by the process...  then make sure all visible
4546             // activities are running, taking care of restarting this
4547             // process.
4548             mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
4549         }
4550     }
4551
4552     private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4553         IBinder threadBinder = thread.asBinder();
4554         // Find the application record.
4555         for (int i=mLruProcesses.size()-1; i>=0; i--) {
4556             ProcessRecord rec = mLruProcesses.get(i);
4557             if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4558                 return i;
4559             }
4560         }
4561         return -1;
4562     }
4563
4564     final ProcessRecord getRecordForAppLocked(
4565             IApplicationThread thread) {
4566         if (thread == null) {
4567             return null;
4568         }
4569
4570         int appIndex = getLRURecordIndexForAppLocked(thread);
4571         return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4572     }
4573
4574     final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4575         // If there are no longer any background processes running,
4576         // and the app that died was not running instrumentation,
4577         // then tell everyone we are now low on memory.
4578         boolean haveBg = false;
4579         for (int i=mLruProcesses.size()-1; i>=0; i--) {
4580             ProcessRecord rec = mLruProcesses.get(i);
4581             if (rec.thread != null
4582                     && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4583                 haveBg = true;
4584                 break;
4585             }
4586         }
4587
4588         if (!haveBg) {
4589             boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4590             if (doReport) {
4591                 long now = SystemClock.uptimeMillis();
4592                 if (now < (mLastMemUsageReportTime+5*60*1000)) {
4593                     doReport = false;
4594                 } else {
4595                     mLastMemUsageReportTime = now;
4596                 }
4597             }
4598             final ArrayList<ProcessMemInfo> memInfos
4599                     = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4600             EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4601             long now = SystemClock.uptimeMillis();
4602             for (int i=mLruProcesses.size()-1; i>=0; i--) {
4603                 ProcessRecord rec = mLruProcesses.get(i);
4604                 if (rec == dyingProc || rec.thread == null) {
4605                     continue;
4606                 }
4607                 if (doReport) {
4608                     memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4609                             rec.setProcState, rec.adjType, rec.makeAdjReason()));
4610                 }
4611                 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4612                     // The low memory report is overriding any current
4613                     // state for a GC request.  Make sure to do
4614                     // heavy/important/visible/foreground processes first.
4615                     if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4616                         rec.lastRequestedGc = 0;
4617                     } else {
4618                         rec.lastRequestedGc = rec.lastLowMemory;
4619                     }
4620                     rec.reportLowMemory = true;
4621                     rec.lastLowMemory = now;
4622                     mProcessesToGc.remove(rec);
4623                     addProcessToGcListLocked(rec);
4624                 }
4625             }
4626             if (doReport) {
4627                 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4628                 mHandler.sendMessage(msg);
4629             }
4630             scheduleAppGcsLocked();
4631         }
4632     }
4633
4634     final void appDiedLocked(ProcessRecord app) {
4635        appDiedLocked(app, app.pid, app.thread, false);
4636     }
4637
4638     final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
4639             boolean fromBinderDied) {
4640         // First check if this ProcessRecord is actually active for the pid.
4641         synchronized (mPidsSelfLocked) {
4642             ProcessRecord curProc = mPidsSelfLocked.get(pid);
4643             if (curProc != app) {
4644                 Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
4645                 return;
4646             }
4647         }
4648
4649         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4650         synchronized (stats) {
4651             stats.noteProcessDiedLocked(app.info.uid, pid);
4652         }
4653
4654         if (!app.killed) {
4655             if (!fromBinderDied) {
4656                 Process.killProcessQuiet(pid);
4657             }
4658             killProcessGroup(app.info.uid, pid);
4659             app.killed = true;
4660         }
4661
4662         // Clean up already done if the process has been re-started.
4663         if (app.pid == pid && app.thread != null &&
4664                 app.thread.asBinder() == thread.asBinder()) {
4665             boolean doLowMem = app.instrumentationClass == null;
4666             boolean doOomAdj = doLowMem;
4667             if (!app.killedByAm) {
4668                 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4669                         + ") has died");
4670                 mAllowLowerMemLevel = true;
4671             } else {
4672                 // Note that we always want to do oom adj to update our state with the
4673                 // new number of procs.
4674                 mAllowLowerMemLevel = false;
4675                 doLowMem = false;
4676             }
4677             EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4678             if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
4679                 "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
4680             handleAppDiedLocked(app, false, true);
4681
4682             if (doOomAdj) {
4683                 updateOomAdjLocked();
4684             }
4685             if (doLowMem) {
4686                 doLowMemReportIfNeededLocked(app);
4687             }
4688         } else if (app.pid != pid) {
4689             // A new process has already been started.
4690             Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4691                     + ") has died and restarted (pid " + app.pid + ").");
4692             EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4693         } else if (DEBUG_PROCESSES) {
4694             Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
4695                     + thread.asBinder());
4696         }
4697     }
4698
4699     /**
4700      * If a stack trace dump file is configured, dump process stack traces.
4701      * @param clearTraces causes the dump file to be erased prior to the new
4702      *    traces being written, if true; when false, the new traces will be
4703      *    appended to any existing file content.
4704      * @param firstPids of dalvik VM processes to dump stack traces for first
4705      * @param lastPids of dalvik VM processes to dump stack traces for last
4706      * @param nativeProcs optional list of native process names to dump stack crawls
4707      * @return file containing stack traces, or null if no dump file is configured
4708      */
4709     public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4710             ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4711         String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4712         if (tracesPath == null || tracesPath.length() == 0) {
4713             return null;
4714         }
4715
4716         File tracesFile = new File(tracesPath);
4717         try {
4718             File tracesDir = tracesFile.getParentFile();
4719             if (!tracesDir.exists()) {
4720                 tracesDir.mkdirs();
4721                 if (!SELinux.restorecon(tracesDir)) {
4722                     return null;
4723                 }
4724             }
4725             FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4726
4727             if (clearTraces && tracesFile.exists()) tracesFile.delete();
4728             tracesFile.createNewFile();
4729             FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4730         } catch (IOException e) {
4731             Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4732             return null;
4733         }
4734
4735         dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4736         return tracesFile;
4737     }
4738
4739     private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4740             ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4741         // Use a FileObserver to detect when traces finish writing.
4742         // The order of traces is considered important to maintain for legibility.
4743         FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4744             @Override
4745             public synchronized void onEvent(int event, String path) { notify(); }
4746         };
4747
4748         try {
4749             observer.startWatching();
4750
4751             // First collect all of the stacks of the most important pids.
4752             if (firstPids != null) {
4753                 try {
4754                     int num = firstPids.size();
4755                     for (int i = 0; i < num; i++) {
4756                         synchronized (observer) {
4757                             Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4758                             observer.wait(200);  // Wait for write-close, give up after 200msec
4759                         }
4760                     }
4761                 } catch (InterruptedException e) {
4762                     Slog.wtf(TAG, e);
4763                 }
4764             }
4765
4766             // Next collect the stacks of the native pids
4767             if (nativeProcs != null) {
4768                 int[] pids = Process.getPidsForCommands(nativeProcs);
4769                 if (pids != null) {
4770                     for (int pid : pids) {
4771                         Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4772                     }
4773                 }
4774             }
4775
4776             // Lastly, measure CPU usage.
4777             if (processCpuTracker != null) {
4778                 processCpuTracker.init();
4779                 System.gc();
4780                 processCpuTracker.update();
4781                 try {
4782                     synchronized (processCpuTracker) {
4783                         processCpuTracker.wait(500); // measure over 1/2 second.
4784                     }
4785                 } catch (InterruptedException e) {
4786                 }
4787                 processCpuTracker.update();
4788
4789                 // We'll take the stack crawls of just the top apps using CPU.
4790                 final int N = processCpuTracker.countWorkingStats();
4791                 int numProcs = 0;
4792                 for (int i=0; i<N && numProcs<5; i++) {
4793                     ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4794                     if (lastPids.indexOfKey(stats.pid) >= 0) {
4795                         numProcs++;
4796                         try {
4797                             synchronized (observer) {
4798                                 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4799                                 observer.wait(200);  // Wait for write-close, give up after 200msec
4800                             }
4801                         } catch (InterruptedException e) {
4802                             Slog.wtf(TAG, e);
4803                         }
4804
4805                     }
4806                 }
4807             }
4808         } finally {
4809             observer.stopWatching();
4810         }
4811     }
4812
4813     final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4814         if (true || IS_USER_BUILD) {
4815             return;
4816         }
4817         String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4818         if (tracesPath == null || tracesPath.length() == 0) {
4819             return;
4820         }
4821
4822         StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4823         StrictMode.allowThreadDiskWrites();
4824         try {
4825             final File tracesFile = new File(tracesPath);
4826             final File tracesDir = tracesFile.getParentFile();
4827             final File tracesTmp = new File(tracesDir, "__tmp__");
4828             try {
4829                 if (!tracesDir.exists()) {
4830                     tracesDir.mkdirs();
4831                     if (!SELinux.restorecon(tracesDir.getPath())) {
4832                         return;
4833                     }
4834                 }
4835                 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4836
4837                 if (tracesFile.exists()) {
4838                     tracesTmp.delete();
4839                     tracesFile.renameTo(tracesTmp);
4840                 }
4841                 StringBuilder sb = new StringBuilder();
4842                 Time tobj = new Time();
4843                 tobj.set(System.currentTimeMillis());
4844                 sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4845                 sb.append(": ");
4846                 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4847                 sb.append(" since ");
4848                 sb.append(msg);
4849                 FileOutputStream fos = new FileOutputStream(tracesFile);
4850                 fos.write(sb.toString().getBytes());
4851                 if (app == null) {
4852                     fos.write("\n*** No application process!".getBytes());
4853                 }
4854                 fos.close();
4855                 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4856             } catch (IOException e) {
4857                 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4858                 return;
4859             }
4860
4861             if (app != null) {
4862                 ArrayList<Integer> firstPids = new ArrayList<Integer>();
4863                 firstPids.add(app.pid);
4864                 dumpStackTraces(tracesPath, firstPids, null, null, null);
4865             }
4866
4867             File lastTracesFile = null;
4868             File curTracesFile = null;
4869             for (int i=9; i>=0; i--) {
4870                 String name = String.format(Locale.US, "slow%02d.txt", i);
4871                 curTracesFile = new File(tracesDir, name);
4872                 if (curTracesFile.exists()) {
4873                     if (lastTracesFile != null) {
4874                         curTracesFile.renameTo(lastTracesFile);
4875                     } else {
4876                         curTracesFile.delete();
4877                     }
4878                 }
4879                 lastTracesFile = curTracesFile;
4880             }
4881             tracesFile.renameTo(curTracesFile);
4882             if (tracesTmp.exists()) {
4883                 tracesTmp.renameTo(tracesFile);
4884             }
4885         } finally {
4886             StrictMode.setThreadPolicy(oldPolicy);
4887         }
4888     }
4889
4890     final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4891             ActivityRecord parent, boolean aboveSystem, final String annotation) {
4892         ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4893         SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4894
4895         if (mController != null) {
4896             try {
4897                 // 0 == continue, -1 = kill process immediately
4898                 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4899                 if (res < 0 && app.pid != MY_PID) {
4900                     app.kill("anr", true);
4901                 }
4902             } catch (RemoteException e) {
4903                 mController = null;
4904                 Watchdog.getInstance().setActivityController(null);
4905             }
4906         }
4907
4908         long anrTime = SystemClock.uptimeMillis();
4909         if (MONITOR_CPU_USAGE) {
4910             updateCpuStatsNow();
4911         }
4912
4913         synchronized (this) {
4914             // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4915             if (mShuttingDown) {
4916                 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4917                 return;
4918             } else if (app.notResponding) {
4919                 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4920                 return;
4921             } else if (app.crashing) {
4922                 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4923                 return;
4924             }
4925
4926             // In case we come through here for the same app before completing
4927             // this one, mark as anring now so we will bail out.
4928             app.notResponding = true;
4929
4930             // Log the ANR to the event log.
4931             EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4932                     app.processName, app.info.flags, annotation);
4933
4934             // Dump thread traces as quickly as we can, starting with "interesting" processes.
4935             firstPids.add(app.pid);
4936
4937             int parentPid = app.pid;
4938             if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4939             if (parentPid != app.pid) firstPids.add(parentPid);
4940
4941             if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4942
4943             for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4944                 ProcessRecord r = mLruProcesses.get(i);
4945                 if (r != null && r.thread != null) {
4946                     int pid = r.pid;
4947                     if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4948                         if (r.persistent) {
4949                             firstPids.add(pid);
4950                         } else {
4951                             lastPids.put(pid, Boolean.TRUE);
4952                         }
4953                     }
4954                 }
4955             }
4956         }
4957
4958         // Log the ANR to the main log.
4959         StringBuilder info = new StringBuilder();
4960         info.setLength(0);
4961         info.append("ANR in ").append(app.processName);
4962         if (activity != null && activity.shortComponentName != null) {
4963             info.append(" (").append(activity.shortComponentName).append(")");
4964         }
4965         info.append("\n");
4966         info.append("PID: ").append(app.pid).append("\n");
4967         if (annotation != null) {
4968             info.append("Reason: ").append(annotation).append("\n");
4969         }
4970         if (parent != null && parent != activity) {
4971             info.append("Parent: ").append(parent.shortComponentName).append("\n");
4972         }
4973
4974         final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4975
4976         File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4977                 NATIVE_STACKS_OF_INTEREST);
4978
4979         String cpuInfo = null;
4980         if (MONITOR_CPU_USAGE) {
4981             updateCpuStatsNow();
4982             synchronized (mProcessCpuTracker) {
4983                 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4984             }
4985             info.append(processCpuTracker.printCurrentLoad());
4986             info.append(cpuInfo);
4987         }
4988
4989         info.append(processCpuTracker.printCurrentState(anrTime));
4990
4991         Slog.e(TAG, info.toString());
4992         if (tracesFile == null) {
4993             // There is no trace file, so dump (only) the alleged culprit's threads to the log
4994             Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4995         }
4996
4997         addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
4998                 cpuInfo, tracesFile, null);
4999
5000         if (mController != null) {
5001             try {
5002                 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
5003                 int res = mController.appNotResponding(app.processName, app.pid, info.toString());
5004                 if (res != 0) {
5005                     if (res < 0 && app.pid != MY_PID) {
5006                         app.kill("anr", true);
5007                     } else {
5008                         synchronized (this) {
5009                             mServices.scheduleServiceTimeoutLocked(app);
5010                         }
5011                     }
5012                     return;
5013                 }
5014             } catch (RemoteException e) {
5015                 mController = null;
5016                 Watchdog.getInstance().setActivityController(null);
5017             }
5018         }
5019
5020         // Unless configured otherwise, swallow ANRs in background processes & kill the process.
5021         boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
5022                 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
5023
5024         synchronized (this) {
5025             mBatteryStatsService.noteProcessAnr(app.processName, app.uid);
5026
5027             if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
5028                 app.kill("bg anr", true);
5029                 return;
5030             }
5031
5032             // Set the app's notResponding state, and look up the errorReportReceiver
5033             makeAppNotRespondingLocked(app,
5034                     activity != null ? activity.shortComponentName : null,
5035                     annotation != null ? "ANR " + annotation : "ANR",
5036                     info.toString());
5037
5038             // Bring up the infamous App Not Responding dialog
5039             Message msg = Message.obtain();
5040             HashMap<String, Object> map = new HashMap<String, Object>();
5041             msg.what = SHOW_NOT_RESPONDING_MSG;
5042             msg.obj = map;
5043             msg.arg1 = aboveSystem ? 1 : 0;
5044             map.put("app", app);
5045             if (activity != null) {
5046                 map.put("activity", activity);
5047             }
5048
5049             mUiHandler.sendMessage(msg);
5050         }
5051     }
5052
5053     final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5054         if (!mLaunchWarningShown) {
5055             mLaunchWarningShown = true;
5056             mUiHandler.post(new Runnable() {
5057                 @Override
5058                 public void run() {
5059                     synchronized (ActivityManagerService.this) {
5060                         final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5061                         d.show();
5062                         mUiHandler.postDelayed(new Runnable() {
5063                             @Override
5064                             public void run() {
5065                                 synchronized (ActivityManagerService.this) {
5066                                     d.dismiss();
5067                                     mLaunchWarningShown = false;
5068                                 }
5069                             }
5070                         }, 4000);
5071                     }
5072                 }
5073             });
5074         }
5075     }
5076
5077     @Override
5078     public boolean clearApplicationUserData(final String packageName,
5079             final IPackageDataObserver observer, int userId) {
5080         enforceNotIsolatedCaller("clearApplicationUserData");
5081         if (packageName != null && packageName.equals(mDeviceOwnerName)) {
5082             throw new SecurityException("Clearing DeviceOwner data is forbidden.");
5083         }
5084         int uid = Binder.getCallingUid();
5085         int pid = Binder.getCallingPid();
5086         userId = handleIncomingUser(pid, uid,
5087                 userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5088         long callingId = Binder.clearCallingIdentity();
5089         try {
5090             IPackageManager pm = AppGlobals.getPackageManager();
5091             int pkgUid = -1;
5092             synchronized(this) {
5093                 try {
5094                     pkgUid = pm.getPackageUid(packageName, userId);
5095                 } catch (RemoteException e) {
5096                 }
5097                 if (pkgUid == -1) {
5098                     Slog.w(TAG, "Invalid packageName: " + packageName);
5099                     if (observer != null) {
5100                         try {
5101                             observer.onRemoveCompleted(packageName, false);
5102                         } catch (RemoteException e) {
5103                             Slog.i(TAG, "Observer no longer exists.");
5104                         }
5105                     }
5106                     return false;
5107                 }
5108                 if (uid == pkgUid || checkComponentPermission(
5109                         android.Manifest.permission.CLEAR_APP_USER_DATA,
5110                         pid, uid, -1, true)
5111                         == PackageManager.PERMISSION_GRANTED) {
5112                     forceStopPackageLocked(packageName, pkgUid, "clear data");
5113                 } else {
5114                     throw new SecurityException("PID " + pid + " does not have permission "
5115                             + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5116                                     + " of package " + packageName);
5117                 }
5118
5119                 // Remove all tasks match the cleared application package and user
5120                 for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5121                     final TaskRecord tr = mRecentTasks.get(i);
5122                     final String taskPackageName =
5123                             tr.getBaseIntent().getComponent().getPackageName();
5124                     if (tr.userId != userId) continue;
5125                     if (!taskPackageName.equals(packageName)) continue;
5126                     removeTaskByIdLocked(tr.taskId, false);
5127                 }
5128             }
5129
5130             try {
5131                 // Clear application user data
5132                 pm.clearApplicationUserData(packageName, observer, userId);
5133
5134                 synchronized(this) {
5135                     // Remove all permissions granted from/to this package
5136                     removeUriPermissionsForPackageLocked(packageName, userId, true);
5137                 }
5138
5139                 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5140                         Uri.fromParts("package", packageName, null));
5141                 intent.putExtra(Intent.EXTRA_UID, pkgUid);
5142                 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5143                         null, null, 0, null, null, null, null, false, false, userId);
5144             } catch (RemoteException e) {
5145             }
5146         } finally {
5147             Binder.restoreCallingIdentity(callingId);
5148         }
5149         return true;
5150     }
5151
5152     @Override
5153     public void killBackgroundProcesses(final String packageName, int userId) {
5154         if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5155                 != PackageManager.PERMISSION_GRANTED &&
5156                 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5157                         != PackageManager.PERMISSION_GRANTED) {
5158             String msg = "Permission Denial: killBackgroundProcesses() from pid="
5159                     + Binder.getCallingPid()
5160                     + ", uid=" + Binder.getCallingUid()
5161                     + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5162             Slog.w(TAG, msg);
5163             throw new SecurityException(msg);
5164         }
5165
5166         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5167                 userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5168         long callingId = Binder.clearCallingIdentity();
5169         try {
5170             IPackageManager pm = AppGlobals.getPackageManager();
5171             synchronized(this) {
5172                 int appId = -1;
5173                 try {
5174                     appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
5175                 } catch (RemoteException e) {
5176                 }
5177                 if (appId == -1) {
5178                     Slog.w(TAG, "Invalid packageName: " + packageName);
5179                     return;
5180                 }
5181                 killPackageProcessesLocked(packageName, appId, userId,
5182                         ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5183             }
5184         } finally {
5185             Binder.restoreCallingIdentity(callingId);
5186         }
5187     }
5188
5189     @Override
5190     public void killAllBackgroundProcesses() {
5191         if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5192                 != PackageManager.PERMISSION_GRANTED) {
5193             String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5194                     + Binder.getCallingPid()
5195                     + ", uid=" + Binder.getCallingUid()
5196                     + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5197             Slog.w(TAG, msg);
5198             throw new SecurityException(msg);
5199         }
5200
5201         long callingId = Binder.clearCallingIdentity();
5202         try {
5203             synchronized(this) {
5204                 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5205                 final int NP = mProcessNames.getMap().size();
5206                 for (int ip=0; ip<NP; ip++) {
5207                     SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5208                     final int NA = apps.size();
5209                     for (int ia=0; ia<NA; ia++) {
5210                         ProcessRecord app = apps.valueAt(ia);
5211                         if (app.persistent) {
5212                             // we don't kill persistent processes
5213                             continue;
5214                         }
5215                         if (app.removed) {
5216                             procs.add(app);
5217                         } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5218                             app.removed = true;
5219                             procs.add(app);
5220                         }
5221                     }
5222                 }
5223
5224                 int N = procs.size();
5225                 for (int i=0; i<N; i++) {
5226                     removeProcessLocked(procs.get(i), false, true, "kill all background");
5227                 }
5228                 mAllowLowerMemLevel = true;
5229                 updateOomAdjLocked();
5230                 doLowMemReportIfNeededLocked(null);
5231             }
5232         } finally {
5233             Binder.restoreCallingIdentity(callingId);
5234         }
5235     }
5236
5237     @Override
5238     public void forceStopPackage(final String packageName, int userId) {
5239         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5240                 != PackageManager.PERMISSION_GRANTED) {
5241             String msg = "Permission Denial: forceStopPackage() from pid="
5242                     + Binder.getCallingPid()
5243                     + ", uid=" + Binder.getCallingUid()
5244                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5245             Slog.w(TAG, msg);
5246             throw new SecurityException(msg);
5247         }
5248         final int callingPid = Binder.getCallingPid();
5249         userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
5250                 userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5251         long callingId = Binder.clearCallingIdentity();
5252         try {
5253             IPackageManager pm = AppGlobals.getPackageManager();
5254             synchronized(this) {
5255                 int[] users = userId == UserHandle.USER_ALL
5256                         ? getUsersLocked() : new int[] { userId };
5257                 for (int user : users) {
5258                     int pkgUid = -1;
5259                     try {
5260                         pkgUid = pm.getPackageUid(packageName, user);
5261                     } catch (RemoteException e) {
5262                     }
5263                     if (pkgUid == -1) {
5264                         Slog.w(TAG, "Invalid packageName: " + packageName);
5265                         continue;
5266                     }
5267                     try {
5268                         pm.setPackageStoppedState(packageName, true, user);
5269                     } catch (RemoteException e) {
5270                     } catch (IllegalArgumentException e) {
5271                         Slog.w(TAG, "Failed trying to unstop package "
5272                                 + packageName + ": " + e);
5273                     }
5274                     if (isUserRunningLocked(user, false)) {
5275                         forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5276                     }
5277                 }
5278             }
5279         } finally {
5280             Binder.restoreCallingIdentity(callingId);
5281         }
5282     }
5283
5284     @Override
5285     public void addPackageDependency(String packageName) {
5286         synchronized (this) {
5287             int callingPid = Binder.getCallingPid();
5288             if (callingPid == Process.myPid()) {
5289                 //  Yeah, um, no.
5290                 return;
5291             }
5292             ProcessRecord proc;
5293             synchronized (mPidsSelfLocked) {
5294                 proc = mPidsSelfLocked.get(Binder.getCallingPid());
5295             }
5296             if (proc != null) {
5297                 if (proc.pkgDeps == null) {
5298                     proc.pkgDeps = new ArraySet<String>(1);
5299                 }
5300                 proc.pkgDeps.add(packageName);
5301             }
5302         }
5303     }
5304
5305     /*
5306      * The pkg name and app id have to be specified.
5307      */
5308     @Override
5309     public void killApplicationWithAppId(String pkg, int appid, String reason) {
5310         if (pkg == null) {
5311             return;
5312         }
5313         // Make sure the uid is valid.
5314         if (appid < 0) {
5315             Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5316             return;
5317         }
5318         int callerUid = Binder.getCallingUid();
5319         // Only the system server can kill an application
5320         if (UserHandle.getAppId(callerUid) == Process.SYSTEM_UID) {
5321             // Post an aysnc message to kill the application
5322             Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5323             msg.arg1 = appid;
5324             msg.arg2 = 0;
5325             Bundle bundle = new Bundle();
5326             bundle.putString("pkg", pkg);
5327             bundle.putString("reason", reason);
5328             msg.obj = bundle;
5329             mHandler.sendMessage(msg);
5330         } else {
5331             throw new SecurityException(callerUid + " cannot kill pkg: " +
5332                     pkg);
5333         }
5334     }
5335
5336     @Override
5337     public void closeSystemDialogs(String reason) {
5338         enforceNotIsolatedCaller("closeSystemDialogs");
5339
5340         final int pid = Binder.getCallingPid();
5341         final int uid = Binder.getCallingUid();
5342         final long origId = Binder.clearCallingIdentity();
5343         try {
5344             synchronized (this) {
5345                 // Only allow this from foreground processes, so that background
5346                 // applications can't abuse it to prevent system UI from being shown.
5347                 if (uid >= Process.FIRST_APPLICATION_UID) {
5348                     ProcessRecord proc;
5349                     synchronized (mPidsSelfLocked) {
5350                         proc = mPidsSelfLocked.get(pid);
5351                     }
5352                     if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5353                         Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5354                                 + " from background process " + proc);
5355                         return;
5356                     }
5357                 }
5358                 closeSystemDialogsLocked(reason);
5359             }
5360         } finally {
5361             Binder.restoreCallingIdentity(origId);
5362         }
5363     }
5364
5365     void closeSystemDialogsLocked(String reason) {
5366         Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5367         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5368                 | Intent.FLAG_RECEIVER_FOREGROUND);
5369         if (reason != null) {
5370             intent.putExtra("reason", reason);
5371         }
5372         mWindowManager.closeSystemDialogs(reason);
5373
5374         mStackSupervisor.closeSystemDialogsLocked();
5375
5376         broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
5377                 AppOpsManager.OP_NONE, null, false, false,
5378                 -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
5379     }
5380
5381     @Override
5382     public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5383         enforceNotIsolatedCaller("getProcessMemoryInfo");
5384         Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5385         for (int i=pids.length-1; i>=0; i--) {
5386             ProcessRecord proc;
5387             int oomAdj;
5388             synchronized (this) {
5389                 synchronized (mPidsSelfLocked) {
5390                     proc = mPidsSelfLocked.get(pids[i]);
5391                     oomAdj = proc != null ? proc.setAdj : 0;
5392                 }
5393             }
5394             infos[i] = new Debug.MemoryInfo();
5395             Debug.getMemoryInfo(pids[i], infos[i]);
5396             if (proc != null) {
5397                 synchronized (this) {
5398                     if (proc.thread != null && proc.setAdj == oomAdj) {
5399                         // Record this for posterity if the process has been stable.
5400                         proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5401                                 infos[i].getTotalUss(), false, proc.pkgList);
5402                     }
5403                 }
5404             }
5405         }
5406         return infos;
5407     }
5408
5409     @Override
5410     public long[] getProcessPss(int[] pids) {
5411         enforceNotIsolatedCaller("getProcessPss");
5412         long[] pss = new long[pids.length];
5413         for (int i=pids.length-1; i>=0; i--) {
5414             ProcessRecord proc;
5415             int oomAdj;
5416             synchronized (this) {
5417                 synchronized (mPidsSelfLocked) {
5418                     proc = mPidsSelfLocked.get(pids[i]);
5419                     oomAdj = proc != null ? proc.setAdj : 0;
5420                 }
5421             }
5422             long[] tmpUss = new long[1];
5423             pss[i] = Debug.getPss(pids[i], tmpUss, null);
5424             if (proc != null) {
5425                 synchronized (this) {
5426                     if (proc.thread != null && proc.setAdj == oomAdj) {
5427                         // Record this for posterity if the process has been stable.
5428                         proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5429                     }
5430                 }
5431             }
5432         }
5433         return pss;
5434     }
5435
5436     @Override
5437     public void killApplicationProcess(String processName, int uid) {
5438         if (processName == null) {
5439             return;
5440         }
5441
5442         int callerUid = Binder.getCallingUid();
5443         // Only the system server can kill an application
5444         if (callerUid == Process.SYSTEM_UID) {
5445             synchronized (this) {
5446                 ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5447                 if (app != null && app.thread != null) {
5448                     try {
5449                         app.thread.scheduleSuicide();
5450                     } catch (RemoteException e) {
5451                         // If the other end already died, then our work here is done.
5452                     }
5453                 } else {
5454                     Slog.w(TAG, "Process/uid not found attempting kill of "
5455                             + processName + " / " + uid);
5456                 }
5457             }
5458         } else {
5459             throw new SecurityException(callerUid + " cannot kill app process: " +
5460                     processName);
5461         }
5462     }
5463
5464     private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5465         forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5466                 false, true, false, false, UserHandle.getUserId(uid), reason);
5467         Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5468                 Uri.fromParts("package", packageName, null));
5469         if (!mProcessesReady) {
5470             intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5471                     | Intent.FLAG_RECEIVER_FOREGROUND);
5472         }
5473         intent.putExtra(Intent.EXTRA_UID, uid);
5474         intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5475         broadcastIntentLocked(null, null, intent,
5476                 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5477                 null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5478     }
5479
5480     private void forceStopUserLocked(int userId, String reason) {
5481         forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
5482         Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
5483         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5484                 | Intent.FLAG_RECEIVER_FOREGROUND);
5485         intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5486         broadcastIntentLocked(null, null, intent,
5487                 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5488                 null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
5489     }
5490
5491     private final boolean killPackageProcessesLocked(String packageName, int appId,
5492             int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5493             boolean doit, boolean evenPersistent, String reason) {
5494         ArrayList<ProcessRecord> procs = new ArrayList<>();
5495
5496         // Remove all processes this package may have touched: all with the
5497         // same UID (except for the system or root user), and all whose name
5498         // matches the package name.
5499         final int NP = mProcessNames.getMap().size();
5500         for (int ip=0; ip<NP; ip++) {
5501             SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5502             final int NA = apps.size();
5503             for (int ia=0; ia<NA; ia++) {
5504                 ProcessRecord app = apps.valueAt(ia);
5505                 if (app.persistent && !evenPersistent) {
5506                     // we don't kill persistent processes
5507                     continue;
5508                 }
5509                 if (app.removed) {
5510                     if (doit) {
5511                         procs.add(app);
5512                     }
5513                     continue;
5514                 }
5515
5516                 // Skip process if it doesn't meet our oom adj requirement.
5517                 if (app.setAdj < minOomAdj) {
5518                     continue;
5519                 }
5520
5521                 // If no package is specified, we call all processes under the
5522                 // give user id.
5523                 if (packageName == null) {
5524                     if (userId != UserHandle.USER_ALL && app.userId != userId) {
5525                         continue;
5526                     }
5527                     if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5528                         continue;
5529                     }
5530                 // Package has been specified, we want to hit all processes
5531                 // that match it.  We need to qualify this by the processes
5532                 // that are running under the specified app and user ID.
5533                 } else {
5534                     final boolean isDep = app.pkgDeps != null
5535                             && app.pkgDeps.contains(packageName);
5536                     if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5537                         continue;
5538                     }
5539                     if (userId != UserHandle.USER_ALL && app.userId != userId) {
5540                         continue;
5541                     }
5542                     if (!app.pkgList.containsKey(packageName) && !isDep) {
5543                         continue;
5544                     }
5545                 }
5546
5547                 // Process has passed all conditions, kill it!
5548                 if (!doit) {
5549                     return true;
5550                 }
5551                 app.removed = true;
5552                 procs.add(app);
5553             }
5554         }
5555
5556         int N = procs.size();
5557         for (int i=0; i<N; i++) {
5558             removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5559         }
5560         updateOomAdjLocked();
5561         return N > 0;
5562     }
5563
5564     private void cleanupDisabledPackageComponentsLocked(
5565             String packageName, int userId, boolean killProcess, String[] changedClasses) {
5566
5567         Set<String> disabledClasses = null;
5568         boolean packageDisabled = false;
5569         IPackageManager pm = AppGlobals.getPackageManager();
5570
5571         if (changedClasses == null) {
5572             // Nothing changed...
5573             return;
5574         }
5575
5576         // Determine enable/disable state of the package and its components.
5577         int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5578         for (int i = changedClasses.length - 1; i >= 0; i--) {
5579             final String changedClass = changedClasses[i];
5580
5581             if (changedClass.equals(packageName)) {
5582                 try {
5583                     // Entire package setting changed
5584                     enabled = pm.getApplicationEnabledSetting(packageName,
5585                             (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_OWNER);
5586                 } catch (Exception e) {
5587                     // No such package/component; probably racing with uninstall.  In any
5588                     // event it means we have nothing further to do here.
5589                     return;
5590                 }
5591                 packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5592                         && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5593                 if (packageDisabled) {
5594                     // Entire package is disabled.
5595                     // No need to continue to check component states.
5596                     disabledClasses = null;
5597                     break;
5598                 }
5599             } else {
5600                 try {
5601                     enabled = pm.getComponentEnabledSetting(
5602                             new ComponentName(packageName, changedClass),
5603                             (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_OWNER);
5604                 } catch (Exception e) {
5605                     // As above, probably racing with uninstall.
5606                     return;
5607                 }
5608                 if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5609                         && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
5610                     if (disabledClasses == null) {
5611                         disabledClasses = new ArraySet<>(changedClasses.length);
5612                     }
5613                     disabledClasses.add(changedClass);
5614                 }
5615             }
5616         }
5617
5618         if (!packageDisabled && disabledClasses == null) {
5619             // Nothing to do here...
5620             return;
5621         }
5622
5623         // Clean-up disabled activities.
5624         if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
5625                 packageName, disabledClasses, true, false, userId) && mBooted) {
5626             mStackSupervisor.resumeTopActivitiesLocked();
5627             mStackSupervisor.scheduleIdleLocked();
5628         }
5629
5630         // Clean-up disabled tasks
5631         cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
5632
5633         // Clean-up disabled services.
5634         mServices.bringDownDisabledPackageServicesLocked(
5635                 packageName, disabledClasses, userId, false, killProcess, true);
5636
5637         // Clean-up disabled providers.
5638         ArrayList<ContentProviderRecord> providers = new ArrayList<>();
5639         mProviderMap.collectPackageProvidersLocked(
5640                 packageName, disabledClasses, true, false, userId, providers);
5641         for (int i = providers.size() - 1; i >= 0; i--) {
5642             removeDyingProviderLocked(null, providers.get(i), true);
5643         }
5644
5645         // Clean-up disabled broadcast receivers.
5646         for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
5647             mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
5648                     packageName, disabledClasses, userId, true);
5649         }
5650
5651     }
5652
5653     private final boolean forceStopPackageLocked(String packageName, int appId,
5654             boolean callerWillRestart, boolean purgeCache, boolean doit,
5655             boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5656         int i;
5657
5658         if (userId == UserHandle.USER_ALL && packageName == null) {
5659             Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5660         }
5661
5662         if (appId < 0 && packageName != null) {
5663             try {
5664                 appId = UserHandle.getAppId(
5665                         AppGlobals.getPackageManager().getPackageUid(packageName, 0));
5666             } catch (RemoteException e) {
5667             }
5668         }
5669
5670         if (doit) {
5671             if (packageName != null) {
5672                 Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
5673                         + " user=" + userId + ": " + reason);
5674             } else {
5675                 Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5676             }
5677
5678             final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5679             for (int ip = pmap.size() - 1; ip >= 0; ip--) {
5680                 SparseArray<Long> ba = pmap.valueAt(ip);
5681                 for (i = ba.size() - 1; i >= 0; i--) {
5682                     boolean remove = false;
5683                     final int entUid = ba.keyAt(i);
5684                     if (packageName != null) {
5685                         if (userId == UserHandle.USER_ALL) {
5686                             if (UserHandle.getAppId(entUid) == appId) {
5687                                 remove = true;
5688                             }
5689                         } else {
5690                             if (entUid == UserHandle.getUid(userId, appId)) {
5691                                 remove = true;
5692                             }
5693                         }
5694                     } else if (UserHandle.getUserId(entUid) == userId) {
5695                         remove = true;
5696                     }
5697                     if (remove) {
5698                         ba.removeAt(i);
5699                     }
5700                 }
5701                 if (ba.size() == 0) {
5702                     pmap.removeAt(ip);
5703                 }
5704             }
5705         }
5706
5707         boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
5708                 -100, callerWillRestart, true, doit, evenPersistent,
5709                 packageName == null ? ("stop user " + userId) : ("stop " + packageName));
5710
5711         if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
5712                 packageName, null, doit, evenPersistent, userId)) {
5713             if (!doit) {
5714                 return true;
5715             }
5716             didSomething = true;
5717         }
5718
5719         if (mServices.bringDownDisabledPackageServicesLocked(
5720                 packageName, null, userId, evenPersistent, true, doit)) {
5721             if (!doit) {
5722                 return true;
5723             }
5724             didSomething = true;
5725         }
5726
5727         if (packageName == null) {
5728             // Remove all sticky broadcasts from this user.
5729             mStickyBroadcasts.remove(userId);
5730         }
5731
5732         ArrayList<ContentProviderRecord> providers = new ArrayList<>();
5733         if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
5734                 userId, providers)) {
5735             if (!doit) {
5736                 return true;
5737             }
5738             didSomething = true;
5739         }
5740         for (i = providers.size() - 1; i >= 0; i--) {
5741             removeDyingProviderLocked(null, providers.get(i), true);
5742         }
5743
5744         // Remove transient permissions granted from/to this package/user
5745         removeUriPermissionsForPackageLocked(packageName, userId, false);
5746
5747         if (doit) {
5748             for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
5749                 didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
5750                         packageName, null, userId, doit);
5751             }
5752         }
5753
5754         if (packageName == null || uninstalling) {
5755             // Remove pending intents.  For now we only do this when force
5756             // stopping users, because we have some problems when doing this
5757             // for packages -- app widgets are not currently cleaned up for
5758             // such packages, so they can be left with bad pending intents.
5759             if (mIntentSenderRecords.size() > 0) {
5760                 Iterator<WeakReference<PendingIntentRecord>> it
5761                         = mIntentSenderRecords.values().iterator();
5762                 while (it.hasNext()) {
5763                     WeakReference<PendingIntentRecord> wpir = it.next();
5764                     if (wpir == null) {
5765                         it.remove();
5766                         continue;
5767                     }
5768                     PendingIntentRecord pir = wpir.get();
5769                     if (pir == null) {
5770                         it.remove();
5771                         continue;
5772                     }
5773                     if (packageName == null) {
5774                         // Stopping user, remove all objects for the user.
5775                         if (pir.key.userId != userId) {
5776                             // Not the same user, skip it.
5777                             continue;
5778                         }
5779                     } else {
5780                         if (UserHandle.getAppId(pir.uid) != appId) {
5781                             // Different app id, skip it.
5782                             continue;
5783                         }
5784                         if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5785                             // Different user, skip it.
5786                             continue;
5787                         }
5788                         if (!pir.key.packageName.equals(packageName)) {
5789                             // Different package, skip it.
5790                             continue;
5791                         }
5792                     }
5793                     if (!doit) {
5794                         return true;
5795                     }
5796                     didSomething = true;
5797                     it.remove();
5798                     pir.canceled = true;
5799                     if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
5800                         pir.key.activity.pendingResults.remove(pir.ref);
5801                     }
5802                 }
5803             }
5804         }
5805
5806         if (doit) {
5807             if (purgeCache && packageName != null) {
5808                 AttributeCache ac = AttributeCache.instance();
5809                 if (ac != null) {
5810                     ac.removePackage(packageName);
5811                 }
5812             }
5813             if (mBooted) {
5814                 mStackSupervisor.resumeTopActivitiesLocked();
5815                 mStackSupervisor.scheduleIdleLocked();
5816             }
5817         }
5818
5819         return didSomething;
5820     }
5821
5822     private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
5823         ProcessRecord old = mProcessNames.remove(name, uid);
5824         if (old != null) {
5825             old.uidRecord.numProcs--;
5826             if (old.uidRecord.numProcs == 0) {
5827                 // No more processes using this uid, tell clients it is gone.
5828                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
5829                         "No more processes in " + old.uidRecord);
5830                 enqueueUidChangeLocked(old.uidRecord, true);
5831                 mActiveUids.remove(uid);
5832             }
5833             old.uidRecord = null;
5834         }
5835         mIsolatedProcesses.remove(uid);
5836         return old;
5837     }
5838
5839     private final void addProcessNameLocked(ProcessRecord proc) {
5840         // We shouldn't already have a process under this name, but just in case we
5841         // need to clean up whatever may be there now.
5842         ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
5843         if (old == proc && proc.persistent) {
5844             // We are re-adding a persistent process.  Whatevs!  Just leave it there.
5845             Slog.w(TAG, "Re-adding persistent process " + proc);
5846         } else if (old != null) {
5847             Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
5848         }
5849         UidRecord uidRec = mActiveUids.get(proc.uid);
5850         if (uidRec == null) {
5851             uidRec = new UidRecord(proc.uid);
5852             // This is the first appearance of the uid, report it now!
5853             if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
5854                     "Creating new process uid: " + uidRec);
5855             mActiveUids.put(proc.uid, uidRec);
5856             enqueueUidChangeLocked(uidRec, false);
5857         }
5858         proc.uidRecord = uidRec;
5859         uidRec.numProcs++;
5860         mProcessNames.put(proc.processName, proc.uid, proc);
5861         if (proc.isolated) {
5862             mIsolatedProcesses.put(proc.uid, proc);
5863         }
5864     }
5865
5866     private final boolean removeProcessLocked(ProcessRecord app,
5867             boolean callerWillRestart, boolean allowRestart, String reason) {
5868         final String name = app.processName;
5869         final int uid = app.uid;
5870         if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
5871             "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
5872
5873         removeProcessNameLocked(name, uid);
5874         if (mHeavyWeightProcess == app) {
5875             mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5876                     mHeavyWeightProcess.userId, 0));
5877             mHeavyWeightProcess = null;
5878         }
5879         boolean needRestart = false;
5880         if (app.pid > 0 && app.pid != MY_PID) {
5881             int pid = app.pid;
5882             synchronized (mPidsSelfLocked) {
5883                 mPidsSelfLocked.remove(pid);
5884                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5885             }
5886             mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5887             if (app.isolated) {
5888                 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5889             }
5890             boolean willRestart = false;
5891             if (app.persistent && !app.isolated) {
5892                 if (!callerWillRestart) {
5893                     willRestart = true;
5894                 } else {
5895                     needRestart = true;
5896                 }
5897             }
5898             app.kill(reason, true);
5899             handleAppDiedLocked(app, willRestart, allowRestart);
5900             if (willRestart) {
5901                 removeLruProcessLocked(app);
5902                 addAppLocked(app.info, false, null /* ABI override */);
5903             }
5904         } else {
5905             mRemovedProcesses.add(app);
5906         }
5907
5908         return needRestart;
5909     }
5910
5911     private final void processStartTimedOutLocked(ProcessRecord app) {
5912         final int pid = app.pid;
5913         boolean gone = false;
5914         synchronized (mPidsSelfLocked) {
5915             ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5916             if (knownApp != null && knownApp.thread == null) {
5917                 mPidsSelfLocked.remove(pid);
5918                 gone = true;
5919             }
5920         }
5921
5922         if (gone) {
5923             Slog.w(TAG, "Process " + app + " failed to attach");
5924             EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5925                     pid, app.uid, app.processName);
5926             removeProcessNameLocked(app.processName, app.uid);
5927             if (mHeavyWeightProcess == app) {
5928                 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5929                         mHeavyWeightProcess.userId, 0));
5930                 mHeavyWeightProcess = null;
5931             }
5932             mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5933             if (app.isolated) {
5934                 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5935             }
5936             // Take care of any launching providers waiting for this process.
5937             checkAppInLaunchingProvidersLocked(app, true);
5938             // Take care of any services that are waiting for the process.
5939             mServices.processStartTimedOutLocked(app);
5940             app.kill("start timeout", true);
5941             removeLruProcessLocked(app);
5942             if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5943                 Slog.w(TAG, "Unattached app died before backup, skipping");
5944                 try {
5945                     IBackupManager bm = IBackupManager.Stub.asInterface(
5946                             ServiceManager.getService(Context.BACKUP_SERVICE));
5947                     bm.agentDisconnected(app.info.packageName);
5948                 } catch (RemoteException e) {
5949                     // Can't happen; the backup manager is local
5950                 }
5951             }
5952             if (isPendingBroadcastProcessLocked(pid)) {
5953                 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5954                 skipPendingBroadcastLocked(pid);
5955             }
5956         } else {
5957             Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5958         }
5959     }
5960
5961     private final boolean attachApplicationLocked(IApplicationThread thread,
5962             int pid) {
5963
5964         // Find the application record that is being attached...  either via
5965         // the pid if we are running in multiple processes, or just pull the
5966         // next app record if we are emulating process with anonymous threads.
5967         ProcessRecord app;
5968         if (pid != MY_PID && pid >= 0) {
5969             synchronized (mPidsSelfLocked) {
5970                 app = mPidsSelfLocked.get(pid);
5971             }
5972         } else {
5973             app = null;
5974         }
5975
5976         if (app == null) {
5977             Slog.w(TAG, "No pending application record for pid " + pid
5978                     + " (IApplicationThread " + thread + "); dropping process");
5979             EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5980             if (pid > 0 && pid != MY_PID) {
5981                 Process.killProcessQuiet(pid);
5982                 //TODO: killProcessGroup(app.info.uid, pid);
5983             } else {
5984                 try {
5985                     thread.scheduleExit();
5986                 } catch (Exception e) {
5987                     // Ignore exceptions.
5988                 }
5989             }
5990             return false;
5991         }
5992
5993         // If this application record is still attached to a previous
5994         // process, clean it up now.
5995         if (app.thread != null) {
5996             handleAppDiedLocked(app, true, true);
5997         }
5998
5999         // Tell the process all about itself.
6000
6001         if (DEBUG_ALL) Slog.v(
6002                 TAG, "Binding process pid " + pid + " to record " + app);
6003
6004         final String processName = app.processName;
6005         try {
6006             AppDeathRecipient adr = new AppDeathRecipient(
6007                     app, pid, thread);
6008             thread.asBinder().linkToDeath(adr, 0);
6009             app.deathRecipient = adr;
6010         } catch (RemoteException e) {
6011             app.resetPackageList(mProcessStats);
6012             startProcessLocked(app, "link fail", processName);
6013             return false;
6014         }
6015
6016         EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6017
6018         app.makeActive(thread, mProcessStats);
6019         app.curAdj = app.setAdj = -100;
6020         app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
6021         app.forcingToForeground = null;
6022         updateProcessForegroundLocked(app, false, false);
6023         app.hasShownUi = false;
6024         app.debugging = false;
6025         app.cached = false;
6026         app.killedByAm = false;
6027
6028         mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6029
6030         boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6031         List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6032
6033         if (!normalMode) {
6034             Slog.i(TAG, "Launching preboot mode app: " + app);
6035         }
6036
6037         if (DEBUG_ALL) Slog.v(
6038             TAG, "New app record " + app
6039             + " thread=" + thread.asBinder() + " pid=" + pid);
6040         try {
6041             int testMode = IApplicationThread.DEBUG_OFF;
6042             if (mDebugApp != null && mDebugApp.equals(processName)) {
6043                 testMode = mWaitForDebugger
6044                     ? IApplicationThread.DEBUG_WAIT
6045                     : IApplicationThread.DEBUG_ON;
6046                 app.debugging = true;
6047                 if (mDebugTransient) {
6048                     mDebugApp = mOrigDebugApp;
6049                     mWaitForDebugger = mOrigWaitForDebugger;
6050                 }
6051             }
6052             String profileFile = app.instrumentationProfileFile;
6053             ParcelFileDescriptor profileFd = null;
6054             int samplingInterval = 0;
6055             boolean profileAutoStop = false;
6056             if (mProfileApp != null && mProfileApp.equals(processName)) {
6057                 mProfileProc = app;
6058                 profileFile = mProfileFile;
6059                 profileFd = mProfileFd;
6060                 samplingInterval = mSamplingInterval;
6061                 profileAutoStop = mAutoStopProfiler;
6062             }
6063             boolean enableOpenGlTrace = false;
6064             if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
6065                 enableOpenGlTrace = true;
6066                 mOpenGlTraceApp = null;
6067             }
6068
6069             // If the app is being launched for restore or full backup, set it up specially
6070             boolean isRestrictedBackupMode = false;
6071             if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6072                 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
6073                         || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6074                         || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
6075             }
6076
6077             ensurePackageDexOpt(app.instrumentationInfo != null
6078                     ? app.instrumentationInfo.packageName
6079                     : app.info.packageName);
6080             if (app.instrumentationClass != null) {
6081                 ensurePackageDexOpt(app.instrumentationClass.getPackageName());
6082             }
6083             if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
6084                     + processName + " with config " + mConfiguration);
6085             ApplicationInfo appInfo = app.instrumentationInfo != null
6086                     ? app.instrumentationInfo : app.info;
6087             app.compat = compatibilityInfoForPackageLocked(appInfo);
6088             if (profileFd != null) {
6089                 profileFd = profileFd.dup();
6090             }
6091             ProfilerInfo profilerInfo = profileFile == null ? null
6092                     : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6093             thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6094                     profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6095                     app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
6096                     isRestrictedBackupMode || !normalMode, app.persistent,
6097                     new Configuration(mConfiguration), app.compat,
6098                     getCommonServicesLocked(app.isolated),
6099                     mCoreSettingsObserver.getCoreSettingsLocked());
6100             updateLruProcessLocked(app, false, null);
6101             app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6102         } catch (Exception e) {
6103             // todo: Yikes!  What should we do?  For now we will try to
6104             // start another process, but that could easily get us in
6105             // an infinite loop of restarting processes...
6106             Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6107
6108             app.resetPackageList(mProcessStats);
6109             app.unlinkDeathRecipient();
6110             startProcessLocked(app, "bind fail", processName);
6111             return false;
6112         }
6113
6114         // Remove this record from the list of starting applications.
6115         mPersistentStartingProcesses.remove(app);
6116         if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
6117                 "Attach application locked removing on hold: " + app);
6118         mProcessesOnHold.remove(app);
6119
6120         boolean badApp = false;
6121         boolean didSomething = false;
6122
6123         // See if the top visible activity is waiting to run in this process...
6124         if (normalMode) {
6125             try {
6126                 if (mStackSupervisor.attachApplicationLocked(app)) {
6127                     didSomething = true;
6128                 }
6129             } catch (Exception e) {
6130                 Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6131                 badApp = true;
6132             }
6133         }
6134
6135         // Find any services that should be running in this process...
6136         if (!badApp) {
6137             try {
6138                 didSomething |= mServices.attachApplicationLocked(app, processName);
6139             } catch (Exception e) {
6140                 Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6141                 badApp = true;
6142             }
6143         }
6144
6145         // Check if a next-broadcast receiver is in this process...
6146         if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6147             try {
6148                 didSomething |= sendPendingBroadcastsLocked(app);
6149             } catch (Exception e) {
6150                 // If the app died trying to launch the receiver we declare it 'bad'
6151                 Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6152                 badApp = true;
6153             }
6154         }
6155
6156         // Check whether the next backup agent is in this process...
6157         if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6158             if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
6159                     "New app is backup target, launching agent for " + app);
6160             ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
6161             try {
6162                 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6163                         compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6164                         mBackupTarget.backupMode);
6165             } catch (Exception e) {
6166                 Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6167                 badApp = true;
6168             }
6169         }
6170
6171         if (badApp) {
6172             app.kill("error during init", true);
6173             handleAppDiedLocked(app, false, true);
6174             return false;
6175         }
6176
6177         if (!didSomething) {
6178             updateOomAdjLocked();
6179         }
6180
6181         return true;
6182     }
6183
6184     @Override
6185     public final void attachApplication(IApplicationThread thread) {
6186         synchronized (this) {
6187             int callingPid = Binder.getCallingPid();
6188             final long origId = Binder.clearCallingIdentity();
6189             attachApplicationLocked(thread, callingPid);
6190             Binder.restoreCallingIdentity(origId);
6191         }
6192     }
6193
6194     @Override
6195     public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6196         final long origId = Binder.clearCallingIdentity();
6197         synchronized (this) {
6198             ActivityStack stack = ActivityRecord.getStackLocked(token);
6199             if (stack != null) {
6200                 ActivityRecord r =
6201                         mStackSupervisor.activityIdleInternalLocked(token, false, config);
6202                 if (stopProfiling) {
6203                     if ((mProfileProc == r.app) && (mProfileFd != null)) {
6204                         try {
6205                             mProfileFd.close();
6206                         } catch (IOException e) {
6207                         }
6208                         clearProfilerLocked();
6209                     }
6210                 }
6211             }
6212         }
6213         Binder.restoreCallingIdentity(origId);
6214     }
6215
6216     void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6217         mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6218                 finishBooting ? 1 : 0, enableScreen ? 1 : 0));
6219     }
6220
6221     void enableScreenAfterBoot() {
6222         EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6223                 SystemClock.uptimeMillis());
6224         mWindowManager.enableScreenAfterBoot();
6225
6226         synchronized (this) {
6227             updateEventDispatchingLocked();
6228         }
6229     }
6230
6231     @Override
6232     public void showBootMessage(final CharSequence msg, final boolean always) {
6233         if (Binder.getCallingUid() != Process.myUid()) {
6234             // These days only the core system can call this, so apps can't get in
6235             // the way of what we show about running them.
6236         }
6237         mWindowManager.showBootMessage(msg, always);
6238     }
6239
6240     @Override
6241     public void keyguardWaitingForActivityDrawn() {
6242         enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6243         final long token = Binder.clearCallingIdentity();
6244         try {
6245             synchronized (this) {
6246                 if (DEBUG_LOCKSCREEN) logLockScreen("");
6247                 mWindowManager.keyguardWaitingForActivityDrawn();
6248                 if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6249                     mLockScreenShown = LOCK_SCREEN_LEAVING;
6250                     updateSleepIfNeededLocked();
6251                 }
6252             }
6253         } finally {
6254             Binder.restoreCallingIdentity(token);
6255         }
6256     }
6257
6258     @Override
6259     public void keyguardGoingAway(boolean disableWindowAnimations,
6260             boolean keyguardGoingToNotificationShade) {
6261         enforceNotIsolatedCaller("keyguardGoingAway");
6262         final long token = Binder.clearCallingIdentity();
6263         try {
6264             synchronized (this) {
6265                 if (DEBUG_LOCKSCREEN) logLockScreen("");
6266                 mWindowManager.keyguardGoingAway(disableWindowAnimations,
6267                         keyguardGoingToNotificationShade);
6268                 if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6269                     mLockScreenShown = LOCK_SCREEN_HIDDEN;
6270                     updateSleepIfNeededLocked();
6271                 }
6272             }
6273         } finally {
6274             Binder.restoreCallingIdentity(token);
6275         }
6276     }
6277
6278     final void finishBooting() {
6279         synchronized (this) {
6280             if (!mBootAnimationComplete) {
6281                 mCallFinishBooting = true;
6282                 return;
6283             }
6284             mCallFinishBooting = false;
6285         }
6286
6287         ArraySet<String> completedIsas = new ArraySet<String>();
6288         for (String abi : Build.SUPPORTED_ABIS) {
6289             Process.establishZygoteConnectionForAbi(abi);
6290             final String instructionSet = VMRuntime.getInstructionSet(abi);
6291             if (!completedIsas.contains(instructionSet)) {
6292                 if (mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi)) != 0) {
6293                     Slog.e(TAG, "Unable to mark boot complete for abi: " + abi);
6294                 }
6295                 completedIsas.add(instructionSet);
6296             }
6297         }
6298
6299         IntentFilter pkgFilter = new IntentFilter();
6300         pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6301         pkgFilter.addDataScheme("package");
6302         mContext.registerReceiver(new BroadcastReceiver() {
6303             @Override
6304             public void onReceive(Context context, Intent intent) {
6305                 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6306                 if (pkgs != null) {
6307                     for (String pkg : pkgs) {
6308                         synchronized (ActivityManagerService.this) {
6309                             if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6310                                     0, "query restart")) {
6311                                 setResultCode(Activity.RESULT_OK);
6312                                 return;
6313                             }
6314                         }
6315                     }
6316                 }
6317             }
6318         }, pkgFilter);
6319
6320         IntentFilter dumpheapFilter = new IntentFilter();
6321         dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
6322         mContext.registerReceiver(new BroadcastReceiver() {
6323             @Override
6324             public void onReceive(Context context, Intent intent) {
6325                 if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
6326                     mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
6327                 } else {
6328                     mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
6329                 }
6330             }
6331         }, dumpheapFilter);
6332
6333         // Let system services know.
6334         mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6335
6336         synchronized (this) {
6337             // Ensure that any processes we had put on hold are now started
6338             // up.
6339             final int NP = mProcessesOnHold.size();
6340             if (NP > 0) {
6341                 ArrayList<ProcessRecord> procs =
6342                     new ArrayList<ProcessRecord>(mProcessesOnHold);
6343                 for (int ip=0; ip<NP; ip++) {
6344                     if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
6345                             + procs.get(ip));
6346                     startProcessLocked(procs.get(ip), "on-hold", null);
6347                 }
6348             }
6349
6350             if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6351                 // Start looking for apps that are abusing wake locks.
6352                 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6353                 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6354                 // Tell anyone interested that we are done booting!
6355                 SystemProperties.set("sys.boot_completed", "1");
6356
6357                 // And trigger dev.bootcomplete if we are not showing encryption progress
6358                 if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6359                     || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6360                     SystemProperties.set("dev.bootcomplete", "1");
6361                 }
6362                 for (int i=0; i<mStartedUsers.size(); i++) {
6363                     UserState uss = mStartedUsers.valueAt(i);
6364                     if (uss.mState == UserState.STATE_BOOTING) {
6365                         uss.mState = UserState.STATE_RUNNING;
6366                         final int userId = mStartedUsers.keyAt(i);
6367                         Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
6368                         intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
6369                         intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
6370                         broadcastIntentLocked(null, null, intent, null,
6371                                 new IIntentReceiver.Stub() {
6372                                     @Override
6373                                     public void performReceive(Intent intent, int resultCode,
6374                                             String data, Bundle extras, boolean ordered,
6375                                             boolean sticky, int sendingUser) {
6376                                         synchronized (ActivityManagerService.this) {
6377                                             requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6378                                                     true, false);
6379                                         }
6380                                     }
6381                                 },
6382                                 0, null, null,
6383                                 new String[] {android.Manifest.permission.RECEIVE_BOOT_COMPLETED},
6384                                 AppOpsManager.OP_NONE, null, true, false,
6385                                 MY_PID, Process.SYSTEM_UID, userId);
6386                     }
6387                 }
6388                 scheduleStartProfilesLocked();
6389             }
6390         }
6391     }
6392
6393     @Override
6394     public void bootAnimationComplete() {
6395         final boolean callFinishBooting;
6396         synchronized (this) {
6397             callFinishBooting = mCallFinishBooting;
6398             mBootAnimationComplete = true;
6399         }
6400         if (callFinishBooting) {
6401             finishBooting();
6402         }
6403     }
6404
6405     final void ensureBootCompleted() {
6406         boolean booting;
6407         boolean enableScreen;
6408         synchronized (this) {
6409             booting = mBooting;
6410             mBooting = false;
6411             enableScreen = !mBooted;
6412             mBooted = true;
6413         }
6414
6415         if (booting) {
6416             finishBooting();
6417         }
6418
6419         if (enableScreen) {
6420             enableScreenAfterBoot();
6421         }
6422     }
6423
6424     @Override
6425     public final void activityResumed(IBinder token) {
6426         final long origId = Binder.clearCallingIdentity();
6427         synchronized(this) {
6428             ActivityStack stack = ActivityRecord.getStackLocked(token);
6429             if (stack != null) {
6430                 ActivityRecord.activityResumedLocked(token);
6431             }
6432         }
6433         Binder.restoreCallingIdentity(origId);
6434     }
6435
6436     @Override
6437     public final void activityPaused(IBinder token) {
6438         final long origId = Binder.clearCallingIdentity();
6439         synchronized(this) {
6440             ActivityStack stack = ActivityRecord.getStackLocked(token);
6441             if (stack != null) {
6442                 stack.activityPausedLocked(token, false);
6443             }
6444         }
6445         Binder.restoreCallingIdentity(origId);
6446     }
6447
6448     @Override
6449     public final void activityStopped(IBinder token, Bundle icicle,
6450             PersistableBundle persistentState, CharSequence description) {
6451         if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
6452
6453         // Refuse possible leaked file descriptors
6454         if (icicle != null && icicle.hasFileDescriptors()) {
6455             throw new IllegalArgumentException("File descriptors passed in Bundle");
6456         }
6457
6458         final long origId = Binder.clearCallingIdentity();
6459
6460         synchronized (this) {
6461             ActivityRecord r = ActivityRecord.isInStackLocked(token);
6462             if (r != null) {
6463                 r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6464             }
6465         }
6466
6467         trimApplications();
6468
6469         Binder.restoreCallingIdentity(origId);
6470     }
6471
6472     @Override
6473     public final void activityDestroyed(IBinder token) {
6474         if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
6475         synchronized (this) {
6476             ActivityStack stack = ActivityRecord.getStackLocked(token);
6477             if (stack != null) {
6478                 stack.activityDestroyedLocked(token, "activityDestroyed");
6479             }
6480         }
6481     }
6482
6483     @Override
6484     public final void backgroundResourcesReleased(IBinder token) {
6485         final long origId = Binder.clearCallingIdentity();
6486         try {
6487             synchronized (this) {
6488                 ActivityStack stack = ActivityRecord.getStackLocked(token);
6489                 if (stack != null) {
6490                     stack.backgroundResourcesReleased();
6491                 }
6492             }
6493         } finally {
6494             Binder.restoreCallingIdentity(origId);
6495         }
6496     }
6497
6498     @Override
6499     public final void notifyLaunchTaskBehindComplete(IBinder token) {
6500         mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6501     }
6502
6503     @Override
6504     public final void notifyEnterAnimationComplete(IBinder token) {
6505         mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6506     }
6507
6508     @Override
6509     public String getCallingPackage(IBinder token) {
6510         synchronized (this) {
6511             ActivityRecord r = getCallingRecordLocked(token);
6512             return r != null ? r.info.packageName : null;
6513         }
6514     }
6515
6516     @Override
6517     public ComponentName getCallingActivity(IBinder token) {
6518         synchronized (this) {
6519             ActivityRecord r = getCallingRecordLocked(token);
6520             return r != null ? r.intent.getComponent() : null;
6521         }
6522     }
6523
6524     private ActivityRecord getCallingRecordLocked(IBinder token) {
6525         ActivityRecord r = ActivityRecord.isInStackLocked(token);
6526         if (r == null) {
6527             return null;
6528         }
6529         return r.resultTo;
6530     }
6531
6532     @Override
6533     public ComponentName getActivityClassForToken(IBinder token) {
6534         synchronized(this) {
6535             ActivityRecord r = ActivityRecord.isInStackLocked(token);
6536             if (r == null) {
6537                 return null;
6538             }
6539             return r.intent.getComponent();
6540         }
6541     }
6542
6543     @Override
6544     public String getPackageForToken(IBinder token) {
6545         synchronized(this) {
6546             ActivityRecord r = ActivityRecord.isInStackLocked(token);
6547             if (r == null) {
6548                 return null;
6549             }
6550             return r.packageName;
6551         }
6552     }
6553
6554     @Override
6555     public boolean isRootVoiceInteraction(IBinder token) {
6556         synchronized(this) {
6557             ActivityRecord r = ActivityRecord.isInStackLocked(token);
6558             if (r == null) {
6559                 return false;
6560             }
6561             return r.rootVoiceInteraction;
6562         }
6563     }
6564
6565     @Override
6566     public IIntentSender getIntentSender(int type,
6567             String packageName, IBinder token, String resultWho,
6568             int requestCode, Intent[] intents, String[] resolvedTypes,
6569             int flags, Bundle options, int userId) {
6570         enforceNotIsolatedCaller("getIntentSender");
6571         // Refuse possible leaked file descriptors
6572         if (intents != null) {
6573             if (intents.length < 1) {
6574                 throw new IllegalArgumentException("Intents array length must be >= 1");
6575             }
6576             for (int i=0; i<intents.length; i++) {
6577                 Intent intent = intents[i];
6578                 if (intent != null) {
6579                     if (intent.hasFileDescriptors()) {
6580                         throw new IllegalArgumentException("File descriptors passed in Intent");
6581                     }
6582                     if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6583                             (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6584                         throw new IllegalArgumentException(
6585                                 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6586                     }
6587                     intents[i] = new Intent(intent);
6588                 }
6589             }
6590             if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6591                 throw new IllegalArgumentException(
6592                         "Intent array length does not match resolvedTypes length");
6593             }
6594         }
6595         if (options != null) {
6596             if (options.hasFileDescriptors()) {
6597                 throw new IllegalArgumentException("File descriptors passed in options");
6598             }
6599         }
6600
6601         synchronized(this) {
6602             int callingUid = Binder.getCallingUid();
6603             int origUserId = userId;
6604             userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6605                     type == ActivityManager.INTENT_SENDER_BROADCAST,
6606                     ALLOW_NON_FULL, "getIntentSender", null);
6607             if (origUserId == UserHandle.USER_CURRENT) {
6608                 // We don't want to evaluate this until the pending intent is
6609                 // actually executed.  However, we do want to always do the
6610                 // security checking for it above.
6611                 userId = UserHandle.USER_CURRENT;
6612             }
6613             try {
6614                 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6615                     int uid = AppGlobals.getPackageManager()
6616                             .getPackageUid(packageName, UserHandle.getUserId(callingUid));
6617                     if (!UserHandle.isSameApp(callingUid, uid)) {
6618                         String msg = "Permission Denial: getIntentSender() from pid="
6619                             + Binder.getCallingPid()
6620                             + ", uid=" + Binder.getCallingUid()
6621                             + ", (need uid=" + uid + ")"
6622                             + " is not allowed to send as package " + packageName;
6623                         Slog.w(TAG, msg);
6624                         throw new SecurityException(msg);
6625                     }
6626                 }
6627
6628                 return getIntentSenderLocked(type, packageName, callingUid, userId,
6629                         token, resultWho, requestCode, intents, resolvedTypes, flags, options);
6630
6631             } catch (RemoteException e) {
6632                 throw new SecurityException(e);
6633             }
6634         }
6635     }
6636
6637     IIntentSender getIntentSenderLocked(int type, String packageName,
6638             int callingUid, int userId, IBinder token, String resultWho,
6639             int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6640             Bundle options) {
6641         if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6642         ActivityRecord activity = null;
6643         if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6644             activity = ActivityRecord.isInStackLocked(token);
6645             if (activity == null) {
6646                 return null;
6647             }
6648             if (activity.finishing) {
6649                 return null;
6650             }
6651         }
6652
6653         final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6654         final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6655         final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6656         flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6657                 |PendingIntent.FLAG_UPDATE_CURRENT);
6658
6659         PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6660                 type, packageName, activity, resultWho,
6661                 requestCode, intents, resolvedTypes, flags, options, userId);
6662         WeakReference<PendingIntentRecord> ref;
6663         ref = mIntentSenderRecords.get(key);
6664         PendingIntentRecord rec = ref != null ? ref.get() : null;
6665         if (rec != null) {
6666             if (!cancelCurrent) {
6667                 if (updateCurrent) {
6668                     if (rec.key.requestIntent != null) {
6669                         rec.key.requestIntent.replaceExtras(intents != null ?
6670                                 intents[intents.length - 1] : null);
6671                     }
6672                     if (intents != null) {
6673                         intents[intents.length-1] = rec.key.requestIntent;
6674                         rec.key.allIntents = intents;
6675                         rec.key.allResolvedTypes = resolvedTypes;
6676                     } else {
6677                         rec.key.allIntents = null;
6678                         rec.key.allResolvedTypes = null;
6679                     }
6680                 }
6681                 return rec;
6682             }
6683             rec.canceled = true;
6684             mIntentSenderRecords.remove(key);
6685         }
6686         if (noCreate) {
6687             return rec;
6688         }
6689         rec = new PendingIntentRecord(this, key, callingUid);
6690         mIntentSenderRecords.put(key, rec.ref);
6691         if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6692             if (activity.pendingResults == null) {
6693                 activity.pendingResults
6694                         = new HashSet<WeakReference<PendingIntentRecord>>();
6695             }
6696             activity.pendingResults.add(rec.ref);
6697         }
6698         return rec;
6699     }
6700
6701     @Override
6702     public void cancelIntentSender(IIntentSender sender) {
6703         if (!(sender instanceof PendingIntentRecord)) {
6704             return;
6705         }
6706         synchronized(this) {
6707             PendingIntentRecord rec = (PendingIntentRecord)sender;
6708             try {
6709                 int uid = AppGlobals.getPackageManager()
6710                         .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
6711                 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6712                     String msg = "Permission Denial: cancelIntentSender() from pid="
6713                         + Binder.getCallingPid()
6714                         + ", uid=" + Binder.getCallingUid()
6715                         + " is not allowed to cancel packges "
6716                         + rec.key.packageName;
6717                     Slog.w(TAG, msg);
6718                     throw new SecurityException(msg);
6719                 }
6720             } catch (RemoteException e) {
6721                 throw new SecurityException(e);
6722             }
6723             cancelIntentSenderLocked(rec, true);
6724         }
6725     }
6726
6727     void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
6728         rec.canceled = true;
6729         mIntentSenderRecords.remove(rec.key);
6730         if (cleanActivity && rec.key.activity != null) {
6731             rec.key.activity.pendingResults.remove(rec.ref);
6732         }
6733     }
6734
6735     @Override
6736     public String getPackageForIntentSender(IIntentSender pendingResult) {
6737         if (!(pendingResult instanceof PendingIntentRecord)) {
6738             return null;
6739         }
6740         try {
6741             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6742             return res.key.packageName;
6743         } catch (ClassCastException e) {
6744         }
6745         return null;
6746     }
6747
6748     @Override
6749     public int getUidForIntentSender(IIntentSender sender) {
6750         if (sender instanceof PendingIntentRecord) {
6751             try {
6752                 PendingIntentRecord res = (PendingIntentRecord)sender;
6753                 return res.uid;
6754             } catch (ClassCastException e) {
6755             }
6756         }
6757         return -1;
6758     }
6759
6760     @Override
6761     public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
6762         if (!(pendingResult instanceof PendingIntentRecord)) {
6763             return false;
6764         }
6765         try {
6766             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6767             if (res.key.allIntents == null) {
6768                 return false;
6769             }
6770             for (int i=0; i<res.key.allIntents.length; i++) {
6771                 Intent intent = res.key.allIntents[i];
6772                 if (intent.getPackage() != null && intent.getComponent() != null) {
6773                     return false;
6774                 }
6775             }
6776             return true;
6777         } catch (ClassCastException e) {
6778         }
6779         return false;
6780     }
6781
6782     @Override
6783     public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
6784         if (!(pendingResult instanceof PendingIntentRecord)) {
6785             return false;
6786         }
6787         try {
6788             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6789             if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6790                 return true;
6791             }
6792             return false;
6793         } catch (ClassCastException e) {
6794         }
6795         return false;
6796     }
6797
6798     @Override
6799     public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6800         if (!(pendingResult instanceof PendingIntentRecord)) {
6801             return null;
6802         }
6803         try {
6804             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6805             return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6806         } catch (ClassCastException e) {
6807         }
6808         return null;
6809     }
6810
6811     @Override
6812     public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6813         if (!(pendingResult instanceof PendingIntentRecord)) {
6814             return null;
6815         }
6816         try {
6817             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6818             synchronized (this) {
6819                 return getTagForIntentSenderLocked(res, prefix);
6820             }
6821         } catch (ClassCastException e) {
6822         }
6823         return null;
6824     }
6825
6826     String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
6827         final Intent intent = res.key.requestIntent;
6828         if (intent != null) {
6829             if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6830                     || res.lastTagPrefix.equals(prefix))) {
6831                 return res.lastTag;
6832             }
6833             res.lastTagPrefix = prefix;
6834             final StringBuilder sb = new StringBuilder(128);
6835             if (prefix != null) {
6836                 sb.append(prefix);
6837             }
6838             if (intent.getAction() != null) {
6839                 sb.append(intent.getAction());
6840             } else if (intent.getComponent() != null) {
6841                 intent.getComponent().appendShortString(sb);
6842             } else {
6843                 sb.append("?");
6844             }
6845             return res.lastTag = sb.toString();
6846         }
6847         return null;
6848     }
6849
6850     @Override
6851     public void setProcessLimit(int max) {
6852         enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6853                 "setProcessLimit()");
6854         synchronized (this) {
6855             mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6856             mProcessLimitOverride = max;
6857         }
6858         trimApplications();
6859     }
6860
6861     @Override
6862     public int getProcessLimit() {
6863         synchronized (this) {
6864             return mProcessLimitOverride;
6865         }
6866     }
6867
6868     void foregroundTokenDied(ForegroundToken token) {
6869         synchronized (ActivityManagerService.this) {
6870             synchronized (mPidsSelfLocked) {
6871                 ForegroundToken cur
6872                     = mForegroundProcesses.get(token.pid);
6873                 if (cur != token) {
6874                     return;
6875                 }
6876                 mForegroundProcesses.remove(token.pid);
6877                 ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6878                 if (pr == null) {
6879                     return;
6880                 }
6881                 pr.forcingToForeground = null;
6882                 updateProcessForegroundLocked(pr, false, false);
6883             }
6884             updateOomAdjLocked();
6885         }
6886     }
6887
6888     @Override
6889     public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6890         enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6891                 "setProcessForeground()");
6892         synchronized(this) {
6893             boolean changed = false;
6894
6895             synchronized (mPidsSelfLocked) {
6896                 ProcessRecord pr = mPidsSelfLocked.get(pid);
6897                 if (pr == null && isForeground) {
6898                     Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6899                     return;
6900                 }
6901                 ForegroundToken oldToken = mForegroundProcesses.get(pid);
6902                 if (oldToken != null) {
6903                     oldToken.token.unlinkToDeath(oldToken, 0);
6904                     mForegroundProcesses.remove(pid);
6905                     if (pr != null) {
6906                         pr.forcingToForeground = null;
6907                     }
6908                     changed = true;
6909                 }
6910                 if (isForeground && token != null) {
6911                     ForegroundToken newToken = new ForegroundToken() {
6912                         @Override
6913                         public void binderDied() {
6914                             foregroundTokenDied(this);
6915                         }
6916                     };
6917                     newToken.pid = pid;
6918                     newToken.token = token;
6919                     try {
6920                         token.linkToDeath(newToken, 0);
6921                         mForegroundProcesses.put(pid, newToken);
6922                         pr.forcingToForeground = token;
6923                         changed = true;
6924                     } catch (RemoteException e) {
6925                         // If the process died while doing this, we will later
6926                         // do the cleanup with the process death link.
6927                     }
6928                 }
6929             }
6930
6931             if (changed) {
6932                 updateOomAdjLocked();
6933             }
6934         }
6935     }
6936
6937     // =========================================================
6938     // PROCESS INFO
6939     // =========================================================
6940
6941     static class ProcessInfoService extends IProcessInfoService.Stub {
6942         final ActivityManagerService mActivityManagerService;
6943         ProcessInfoService(ActivityManagerService activityManagerService) {
6944             mActivityManagerService = activityManagerService;
6945         }
6946
6947         @Override
6948         public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
6949             mActivityManagerService.getProcessStatesForPIDs(/*in*/ pids, /*out*/ states);
6950         }
6951     }
6952
6953     /**
6954      * For each PID in the given input array, write the current process state
6955      * for that process into the output array, or -1 to indicate that no
6956      * process with the given PID exists.
6957      */
6958     public void getProcessStatesForPIDs(/*in*/ int[] pids, /*out*/ int[] states) {
6959         if (pids == null) {
6960             throw new NullPointerException("pids");
6961         } else if (states == null) {
6962             throw new NullPointerException("states");
6963         } else if (pids.length != states.length) {
6964             throw new IllegalArgumentException("input and output arrays have different lengths!");
6965         }
6966
6967         synchronized (mPidsSelfLocked) {
6968             for (int i = 0; i < pids.length; i++) {
6969                 ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
6970                 states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
6971                         pr.curProcState;
6972             }
6973         }
6974     }
6975
6976     // =========================================================
6977     // PERMISSIONS
6978     // =========================================================
6979
6980     static class PermissionController extends IPermissionController.Stub {
6981         ActivityManagerService mActivityManagerService;
6982         PermissionController(ActivityManagerService activityManagerService) {
6983             mActivityManagerService = activityManagerService;
6984         }
6985
6986         @Override
6987         public boolean checkPermission(String permission, int pid, int uid) {
6988             return mActivityManagerService.checkPermission(permission, pid,
6989                     uid) == PackageManager.PERMISSION_GRANTED;
6990         }
6991
6992         @Override
6993         public String[] getPackagesForUid(int uid) {
6994             return mActivityManagerService.mContext.getPackageManager()
6995                     .getPackagesForUid(uid);
6996         }
6997
6998         @Override
6999         public boolean isRuntimePermission(String permission) {
7000             try {
7001                 PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
7002                         .getPermissionInfo(permission, 0);
7003                 return info.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS;
7004             } catch (NameNotFoundException nnfe) {
7005                 Slog.e(TAG, "No such permission: "+ permission, nnfe);
7006             }
7007             return false;
7008         }
7009     }
7010
7011     class IntentFirewallInterface implements IntentFirewall.AMSInterface {
7012         @Override
7013         public int checkComponentPermission(String permission, int pid, int uid,
7014                 int owningUid, boolean exported) {
7015             return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
7016                     owningUid, exported);
7017         }
7018
7019         @Override
7020         public Object getAMSLock() {
7021             return ActivityManagerService.this;
7022         }
7023     }
7024
7025     /**
7026      * This can be called with or without the global lock held.
7027      */
7028     int checkComponentPermission(String permission, int pid, int uid,
7029             int owningUid, boolean exported) {
7030         if (pid == MY_PID) {
7031             return PackageManager.PERMISSION_GRANTED;
7032         }
7033         return ActivityManager.checkComponentPermission(permission, uid,
7034                 owningUid, exported);
7035     }
7036
7037     /**
7038      * As the only public entry point for permissions checking, this method
7039      * can enforce the semantic that requesting a check on a null global
7040      * permission is automatically denied.  (Internally a null permission
7041      * string is used when calling {@link #checkComponentPermission} in cases
7042      * when only uid-based security is needed.)
7043      *
7044      * This can be called with or without the global lock held.
7045      */
7046     @Override
7047     public int checkPermission(String permission, int pid, int uid) {
7048         if (permission == null) {
7049             return PackageManager.PERMISSION_DENIED;
7050         }
7051         return checkComponentPermission(permission, pid, uid, -1, true);
7052     }
7053
7054     @Override
7055     public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
7056         if (permission == null) {
7057             return PackageManager.PERMISSION_DENIED;
7058         }
7059
7060         // We might be performing an operation on behalf of an indirect binder
7061         // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
7062         // client identity accordingly before proceeding.
7063         Identity tlsIdentity = sCallerIdentity.get();
7064         if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7065             Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
7066                     + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
7067             uid = tlsIdentity.uid;
7068             pid = tlsIdentity.pid;
7069         }
7070
7071         return checkComponentPermission(permission, pid, uid, -1, true);
7072     }
7073
7074     /**
7075      * Binder IPC calls go through the public entry point.
7076      * This can be called with or without the global lock held.
7077      */
7078     int checkCallingPermission(String permission) {
7079         return checkPermission(permission,
7080                 Binder.getCallingPid(),
7081                 UserHandle.getAppId(Binder.getCallingUid()));
7082     }
7083
7084     /**
7085      * This can be called with or without the global lock held.
7086      */
7087     void enforceCallingPermission(String permission, String func) {
7088         if (checkCallingPermission(permission)
7089                 == PackageManager.PERMISSION_GRANTED) {
7090             return;
7091         }
7092
7093         String msg = "Permission Denial: " + func + " from pid="
7094                 + Binder.getCallingPid()
7095                 + ", uid=" + Binder.getCallingUid()
7096                 + " requires " + permission;
7097         Slog.w(TAG, msg);
7098         throw new SecurityException(msg);
7099     }
7100
7101     /**
7102      * Determine if UID is holding permissions required to access {@link Uri} in
7103      * the given {@link ProviderInfo}. Final permission checking is always done
7104      * in {@link ContentProvider}.
7105      */
7106     private final boolean checkHoldingPermissionsLocked(
7107             IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
7108         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7109                 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
7110         if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
7111             if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
7112                     != PERMISSION_GRANTED) {
7113                 return false;
7114             }
7115         }
7116         return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
7117     }
7118
7119     private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
7120             GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
7121         if (pi.applicationInfo.uid == uid) {
7122             return true;
7123         } else if (!pi.exported) {
7124             return false;
7125         }
7126
7127         boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
7128         boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
7129         try {
7130             // check if target holds top-level <provider> permissions
7131             if (!readMet && pi.readPermission != null && considerUidPermissions
7132                     && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
7133                 readMet = true;
7134             }
7135             if (!writeMet && pi.writePermission != null && considerUidPermissions
7136                     && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
7137                 writeMet = true;
7138             }
7139
7140             // track if unprotected read/write is allowed; any denied
7141             // <path-permission> below removes this ability
7142             boolean allowDefaultRead = pi.readPermission == null;
7143             boolean allowDefaultWrite = pi.writePermission == null;
7144
7145             // check if target holds any <path-permission> that match uri
7146             final PathPermission[] pps = pi.pathPermissions;
7147             if (pps != null) {
7148                 final String path = grantUri.uri.getPath();
7149                 int i = pps.length;
7150                 while (i > 0 && (!readMet || !writeMet)) {
7151                     i--;
7152                     PathPermission pp = pps[i];
7153                     if (pp.match(path)) {
7154                         if (!readMet) {
7155                             final String pprperm = pp.getReadPermission();
7156                             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7157                                     "Checking read perm for " + pprperm + " for " + pp.getPath()
7158                                     + ": match=" + pp.match(path)
7159                                     + " check=" + pm.checkUidPermission(pprperm, uid));
7160                             if (pprperm != null) {
7161                                 if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7162                                         == PERMISSION_GRANTED) {
7163                                     readMet = true;
7164                                 } else {
7165                                     allowDefaultRead = false;
7166                                 }
7167                             }
7168                         }
7169                         if (!writeMet) {
7170                             final String ppwperm = pp.getWritePermission();
7171                             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7172                                     "Checking write perm " + ppwperm + " for " + pp.getPath()
7173                                     + ": match=" + pp.match(path)
7174                                     + " check=" + pm.checkUidPermission(ppwperm, uid));
7175                             if (ppwperm != null) {
7176                                 if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7177                                         == PERMISSION_GRANTED) {
7178                                     writeMet = true;
7179                                 } else {
7180                                     allowDefaultWrite = false;
7181                                 }
7182                             }
7183                         }
7184                     }
7185                 }
7186             }
7187
7188             // grant unprotected <provider> read/write, if not blocked by
7189             // <path-permission> above
7190             if (allowDefaultRead) readMet = true;
7191             if (allowDefaultWrite) writeMet = true;
7192
7193         } catch (RemoteException e) {
7194             return false;
7195         }
7196
7197         return readMet && writeMet;
7198     }
7199
7200     private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
7201         ProviderInfo pi = null;
7202         ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7203         if (cpr != null) {
7204             pi = cpr.info;
7205         } else {
7206             try {
7207                 pi = AppGlobals.getPackageManager().resolveContentProvider(
7208                         authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
7209             } catch (RemoteException ex) {
7210             }
7211         }
7212         return pi;
7213     }
7214
7215     private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7216         final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7217         if (targetUris != null) {
7218             return targetUris.get(grantUri);
7219         }
7220         return null;
7221     }
7222
7223     private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7224             String targetPkg, int targetUid, GrantUri grantUri) {
7225         ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7226         if (targetUris == null) {
7227             targetUris = Maps.newArrayMap();
7228             mGrantedUriPermissions.put(targetUid, targetUris);
7229         }
7230
7231         UriPermission perm = targetUris.get(grantUri);
7232         if (perm == null) {
7233             perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7234             targetUris.put(grantUri, perm);
7235         }
7236
7237         return perm;
7238     }
7239
7240     private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7241             final int modeFlags) {
7242         final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7243         final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7244                 : UriPermission.STRENGTH_OWNED;
7245
7246         // Root gets to do everything.
7247         if (uid == 0) {
7248             return true;
7249         }
7250
7251         final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7252         if (perms == null) return false;
7253
7254         // First look for exact match
7255         final UriPermission exactPerm = perms.get(grantUri);
7256         if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7257             return true;
7258         }
7259
7260         // No exact match, look for prefixes
7261         final int N = perms.size();
7262         for (int i = 0; i < N; i++) {
7263             final UriPermission perm = perms.valueAt(i);
7264             if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7265                     && perm.getStrength(modeFlags) >= minStrength) {
7266                 return true;
7267             }
7268         }
7269
7270         return false;
7271     }
7272
7273     /**
7274      * @param uri This uri must NOT contain an embedded userId.
7275      * @param userId The userId in which the uri is to be resolved.
7276      */
7277     @Override
7278     public int checkUriPermission(Uri uri, int pid, int uid,
7279             final int modeFlags, int userId, IBinder callerToken) {
7280         enforceNotIsolatedCaller("checkUriPermission");
7281
7282         // Another redirected-binder-call permissions check as in
7283         // {@link checkPermissionWithToken}.
7284         Identity tlsIdentity = sCallerIdentity.get();
7285         if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7286             uid = tlsIdentity.uid;
7287             pid = tlsIdentity.pid;
7288         }
7289
7290         // Our own process gets to do everything.
7291         if (pid == MY_PID) {
7292             return PackageManager.PERMISSION_GRANTED;
7293         }
7294         synchronized (this) {
7295             return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7296                     ? PackageManager.PERMISSION_GRANTED
7297                     : PackageManager.PERMISSION_DENIED;
7298         }
7299     }
7300
7301     /**
7302      * Check if the targetPkg can be granted permission to access uri by
7303      * the callingUid using the given modeFlags.  Throws a security exception
7304      * if callingUid is not allowed to do this.  Returns the uid of the target
7305      * if the URI permission grant should be performed; returns -1 if it is not
7306      * needed (for example targetPkg already has permission to access the URI).
7307      * If you already know the uid of the target, you can supply it in
7308      * lastTargetUid else set that to -1.
7309      */
7310     int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7311             final int modeFlags, int lastTargetUid) {
7312         if (!Intent.isAccessUriMode(modeFlags)) {
7313             return -1;
7314         }
7315
7316         if (targetPkg != null) {
7317             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7318                     "Checking grant " + targetPkg + " permission to " + grantUri);
7319         }
7320
7321         final IPackageManager pm = AppGlobals.getPackageManager();
7322
7323         // If this is not a content: uri, we can't do anything with it.
7324         if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7325             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7326                     "Can't grant URI permission for non-content URI: " + grantUri);
7327             return -1;
7328         }
7329
7330         final String authority = grantUri.uri.getAuthority();
7331         final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7332         if (pi == null) {
7333             Slog.w(TAG, "No content provider found for permission check: " +
7334                     grantUri.uri.toSafeString());
7335             return -1;
7336         }
7337
7338         int targetUid = lastTargetUid;
7339         if (targetUid < 0 && targetPkg != null) {
7340             try {
7341                 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
7342                 if (targetUid < 0) {
7343                     if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7344                             "Can't grant URI permission no uid for: " + targetPkg);
7345                     return -1;
7346                 }
7347             } catch (RemoteException ex) {
7348                 return -1;
7349             }
7350         }
7351
7352         if (targetUid >= 0) {
7353             // First...  does the target actually need this permission?
7354             if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7355                 // No need to grant the target this permission.
7356                 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7357                         "Target " + targetPkg + " already has full permission to " + grantUri);
7358                 return -1;
7359             }
7360         } else {
7361             // First...  there is no target package, so can anyone access it?
7362             boolean allowed = pi.exported;
7363             if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7364                 if (pi.readPermission != null) {
7365                     allowed = false;
7366                 }
7367             }
7368             if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7369                 if (pi.writePermission != null) {
7370                     allowed = false;
7371                 }
7372             }
7373             if (allowed) {
7374                 return -1;
7375             }
7376         }
7377
7378         /* There is a special cross user grant if:
7379          * - The target is on another user.
7380          * - Apps on the current user can access the uri without any uid permissions.
7381          * In this case, we grant a uri permission, even if the ContentProvider does not normally
7382          * grant uri permissions.
7383          */
7384         boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7385                 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7386                 modeFlags, false /*without considering the uid permissions*/);
7387
7388         // Second...  is the provider allowing granting of URI permissions?
7389         if (!specialCrossUserGrant) {
7390             if (!pi.grantUriPermissions) {
7391                 throw new SecurityException("Provider " + pi.packageName
7392                         + "/" + pi.name
7393                         + " does not allow granting of Uri permissions (uri "
7394                         + grantUri + ")");
7395             }
7396             if (pi.uriPermissionPatterns != null) {
7397                 final int N = pi.uriPermissionPatterns.length;
7398                 boolean allowed = false;
7399                 for (int i=0; i<N; i++) {
7400                     if (pi.uriPermissionPatterns[i] != null
7401                             && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7402                         allowed = true;
7403                         break;
7404                     }
7405                 }
7406                 if (!allowed) {
7407                     throw new SecurityException("Provider " + pi.packageName
7408                             + "/" + pi.name
7409                             + " does not allow granting of permission to path of Uri "
7410                             + grantUri);
7411                 }
7412             }
7413         }
7414
7415         // Third...  does the caller itself have permission to access
7416         // this uri?
7417         if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
7418             if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7419                 // Require they hold a strong enough Uri permission
7420                 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7421                     throw new SecurityException("Uid " + callingUid
7422                             + " does not have permission to uri " + grantUri);
7423                 }
7424             }
7425         }
7426         return targetUid;
7427     }
7428
7429     /**
7430      * @param uri This uri must NOT contain an embedded userId.
7431      * @param userId The userId in which the uri is to be resolved.
7432      */
7433     @Override
7434     public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
7435             final int modeFlags, int userId) {
7436         enforceNotIsolatedCaller("checkGrantUriPermission");
7437         synchronized(this) {
7438             return checkGrantUriPermissionLocked(callingUid, targetPkg,
7439                     new GrantUri(userId, uri, false), modeFlags, -1);
7440         }
7441     }
7442
7443     void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
7444             final int modeFlags, UriPermissionOwner owner) {
7445         if (!Intent.isAccessUriMode(modeFlags)) {
7446             return;
7447         }
7448
7449         // So here we are: the caller has the assumed permission
7450         // to the uri, and the target doesn't.  Let's now give this to
7451         // the target.
7452
7453         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7454                 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
7455
7456         final String authority = grantUri.uri.getAuthority();
7457         final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7458         if (pi == null) {
7459             Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
7460             return;
7461         }
7462
7463         if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
7464             grantUri.prefix = true;
7465         }
7466         final UriPermission perm = findOrCreateUriPermissionLocked(
7467                 pi.packageName, targetPkg, targetUid, grantUri);
7468         perm.grantModes(modeFlags, owner);
7469     }
7470
7471     void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7472             final int modeFlags, UriPermissionOwner owner, int targetUserId) {
7473         if (targetPkg == null) {
7474             throw new NullPointerException("targetPkg");
7475         }
7476         int targetUid;
7477         final IPackageManager pm = AppGlobals.getPackageManager();
7478         try {
7479             targetUid = pm.getPackageUid(targetPkg, targetUserId);
7480         } catch (RemoteException ex) {
7481             return;
7482         }
7483
7484         targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
7485                 targetUid);
7486         if (targetUid < 0) {
7487             return;
7488         }
7489
7490         grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
7491                 owner);
7492     }
7493
7494     static class NeededUriGrants extends ArrayList<GrantUri> {
7495         final String targetPkg;
7496         final int targetUid;
7497         final int flags;
7498
7499         NeededUriGrants(String targetPkg, int targetUid, int flags) {
7500             this.targetPkg = targetPkg;
7501             this.targetUid = targetUid;
7502             this.flags = flags;
7503         }
7504     }
7505
7506     /**
7507      * Like checkGrantUriPermissionLocked, but takes an Intent.
7508      */
7509     NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
7510             String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
7511         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7512                 "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
7513                 + " clip=" + (intent != null ? intent.getClipData() : null)
7514                 + " from " + intent + "; flags=0x"
7515                 + Integer.toHexString(intent != null ? intent.getFlags() : 0));
7516
7517         if (targetPkg == null) {
7518             throw new NullPointerException("targetPkg");
7519         }
7520
7521         if (intent == null) {
7522             return null;
7523         }
7524         Uri data = intent.getData();
7525         ClipData clip = intent.getClipData();
7526         if (data == null && clip == null) {
7527             return null;
7528         }
7529         // Default userId for uris in the intent (if they don't specify it themselves)
7530         int contentUserHint = intent.getContentUserHint();
7531         if (contentUserHint == UserHandle.USER_CURRENT) {
7532             contentUserHint = UserHandle.getUserId(callingUid);
7533         }
7534         final IPackageManager pm = AppGlobals.getPackageManager();
7535         int targetUid;
7536         if (needed != null) {
7537             targetUid = needed.targetUid;
7538         } else {
7539             try {
7540                 targetUid = pm.getPackageUid(targetPkg, targetUserId);
7541             } catch (RemoteException ex) {
7542                 return null;
7543             }
7544             if (targetUid < 0) {
7545                 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7546                         "Can't grant URI permission no uid for: " + targetPkg
7547                         + " on user " + targetUserId);
7548                 return null;
7549             }
7550         }
7551         if (data != null) {
7552             GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
7553             targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7554                     targetUid);
7555             if (targetUid > 0) {
7556                 if (needed == null) {
7557                     needed = new NeededUriGrants(targetPkg, targetUid, mode);
7558                 }
7559                 needed.add(grantUri);
7560             }
7561         }
7562         if (clip != null) {
7563             for (int i=0; i<clip.getItemCount(); i++) {
7564                 Uri uri = clip.getItemAt(i).getUri();
7565                 if (uri != null) {
7566                     GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
7567                     targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7568                             targetUid);
7569                     if (targetUid > 0) {
7570                         if (needed == null) {
7571                             needed = new NeededUriGrants(targetPkg, targetUid, mode);
7572                         }
7573                         needed.add(grantUri);
7574                     }
7575                 } else {
7576                     Intent clipIntent = clip.getItemAt(i).getIntent();
7577                     if (clipIntent != null) {
7578                         NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
7579                                 callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
7580                         if (newNeeded != null) {
7581                             needed = newNeeded;
7582                         }
7583                     }
7584                 }
7585             }
7586         }
7587
7588         return needed;
7589     }
7590
7591     /**
7592      * Like grantUriPermissionUncheckedLocked, but takes an Intent.
7593      */
7594     void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
7595             UriPermissionOwner owner) {
7596         if (needed != null) {
7597             for (int i=0; i<needed.size(); i++) {
7598                 GrantUri grantUri = needed.get(i);
7599                 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
7600                         grantUri, needed.flags, owner);
7601             }
7602         }
7603     }
7604
7605     void grantUriPermissionFromIntentLocked(int callingUid,
7606             String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
7607         NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
7608                 intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
7609         if (needed == null) {
7610             return;
7611         }
7612
7613         grantUriPermissionUncheckedFromIntentLocked(needed, owner);
7614     }
7615
7616     /**
7617      * @param uri This uri must NOT contain an embedded userId.
7618      * @param userId The userId in which the uri is to be resolved.
7619      */
7620     @Override
7621     public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
7622             final int modeFlags, int userId) {
7623         enforceNotIsolatedCaller("grantUriPermission");
7624         GrantUri grantUri = new GrantUri(userId, uri, false);
7625         synchronized(this) {
7626             final ProcessRecord r = getRecordForAppLocked(caller);
7627             if (r == null) {
7628                 throw new SecurityException("Unable to find app for caller "
7629                         + caller
7630                         + " when granting permission to uri " + grantUri);
7631             }
7632             if (targetPkg == null) {
7633                 throw new IllegalArgumentException("null target");
7634             }
7635             if (grantUri == null) {
7636                 throw new IllegalArgumentException("null uri");
7637             }
7638
7639             Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
7640                     | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
7641                     | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
7642                     | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
7643
7644             grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
7645                     UserHandle.getUserId(r.uid));
7646         }
7647     }
7648
7649     void removeUriPermissionIfNeededLocked(UriPermission perm) {
7650         if (perm.modeFlags == 0) {
7651             final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7652                     perm.targetUid);
7653             if (perms != null) {
7654                 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7655                         "Removing " + perm.targetUid + " permission to " + perm.uri);
7656
7657                 perms.remove(perm.uri);
7658                 if (perms.isEmpty()) {
7659                     mGrantedUriPermissions.remove(perm.targetUid);
7660                 }
7661             }
7662         }
7663     }
7664
7665     private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
7666         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7667                 "Revoking all granted permissions to " + grantUri);
7668
7669         final IPackageManager pm = AppGlobals.getPackageManager();
7670         final String authority = grantUri.uri.getAuthority();
7671         final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7672         if (pi == null) {
7673             Slog.w(TAG, "No content provider found for permission revoke: "
7674                     + grantUri.toSafeString());
7675             return;
7676         }
7677
7678         // Does the caller have this permission on the URI?
7679         if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7680             // If they don't have direct access to the URI, then revoke any
7681             // ownerless URI permissions that have been granted to them.
7682             final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7683             if (perms != null) {
7684                 boolean persistChanged = false;
7685                 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7686                     final UriPermission perm = it.next();
7687                     if (perm.uri.sourceUserId == grantUri.sourceUserId
7688                             && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7689                         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7690                                 "Revoking non-owned " + perm.targetUid
7691                                 + " permission to " + perm.uri);
7692                         persistChanged |= perm.revokeModes(
7693                                 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
7694                         if (perm.modeFlags == 0) {
7695                             it.remove();
7696                         }
7697                     }
7698                 }
7699                 if (perms.isEmpty()) {
7700                     mGrantedUriPermissions.remove(callingUid);
7701                 }
7702                 if (persistChanged) {
7703                     schedulePersistUriGrants();
7704                 }
7705             }
7706             return;
7707         }
7708
7709         boolean persistChanged = false;
7710
7711         // Go through all of the permissions and remove any that match.
7712         int N = mGrantedUriPermissions.size();
7713         for (int i = 0; i < N; i++) {
7714             final int targetUid = mGrantedUriPermissions.keyAt(i);
7715             final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7716
7717             for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7718                 final UriPermission perm = it.next();
7719                 if (perm.uri.sourceUserId == grantUri.sourceUserId
7720                         && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7721                     if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7722                                 "Revoking " + perm.targetUid + " permission to " + perm.uri);
7723                     persistChanged |= perm.revokeModes(
7724                             modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7725                     if (perm.modeFlags == 0) {
7726                         it.remove();
7727                     }
7728                 }
7729             }
7730
7731             if (perms.isEmpty()) {
7732                 mGrantedUriPermissions.remove(targetUid);
7733                 N--;
7734                 i--;
7735             }
7736         }
7737
7738         if (persistChanged) {
7739             schedulePersistUriGrants();
7740         }
7741     }
7742
7743     /**
7744      * @param uri This uri must NOT contain an embedded userId.
7745      * @param userId The userId in which the uri is to be resolved.
7746      */
7747     @Override
7748     public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
7749             int userId) {
7750         enforceNotIsolatedCaller("revokeUriPermission");
7751         synchronized(this) {
7752             final ProcessRecord r = getRecordForAppLocked(caller);
7753             if (r == null) {
7754                 throw new SecurityException("Unable to find app for caller "
7755                         + caller
7756                         + " when revoking permission to uri " + uri);
7757             }
7758             if (uri == null) {
7759                 Slog.w(TAG, "revokeUriPermission: null uri");
7760                 return;
7761             }
7762
7763             if (!Intent.isAccessUriMode(modeFlags)) {
7764                 return;
7765             }
7766
7767             final String authority = uri.getAuthority();
7768             final ProviderInfo pi = getProviderInfoLocked(authority, userId);
7769             if (pi == null) {
7770                 Slog.w(TAG, "No content provider found for permission revoke: "
7771                         + uri.toSafeString());
7772                 return;
7773             }
7774
7775             revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
7776         }
7777     }
7778
7779     /**
7780      * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
7781      * given package.
7782      *
7783      * @param packageName Package name to match, or {@code null} to apply to all
7784      *            packages.
7785      * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
7786      *            to all users.
7787      * @param persistable If persistable grants should be removed.
7788      */
7789     private void removeUriPermissionsForPackageLocked(
7790             String packageName, int userHandle, boolean persistable) {
7791         if (userHandle == UserHandle.USER_ALL && packageName == null) {
7792             throw new IllegalArgumentException("Must narrow by either package or user");
7793         }
7794
7795         boolean persistChanged = false;
7796
7797         int N = mGrantedUriPermissions.size();
7798         for (int i = 0; i < N; i++) {
7799             final int targetUid = mGrantedUriPermissions.keyAt(i);
7800             final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7801
7802             // Only inspect grants matching user
7803             if (userHandle == UserHandle.USER_ALL
7804                     || userHandle == UserHandle.getUserId(targetUid)) {
7805                 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7806                     final UriPermission perm = it.next();
7807
7808                     // Only inspect grants matching package
7809                     if (packageName == null || perm.sourcePkg.equals(packageName)
7810                             || perm.targetPkg.equals(packageName)) {
7811                         persistChanged |= perm.revokeModes(persistable
7812                                 ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7813
7814                         // Only remove when no modes remain; any persisted grants
7815                         // will keep this alive.
7816                         if (perm.modeFlags == 0) {
7817                             it.remove();
7818                         }
7819                     }
7820                 }
7821
7822                 if (perms.isEmpty()) {
7823                     mGrantedUriPermissions.remove(targetUid);
7824                     N--;
7825                     i--;
7826                 }
7827             }
7828         }
7829
7830         if (persistChanged) {
7831             schedulePersistUriGrants();
7832         }
7833     }
7834
7835     @Override
7836     public IBinder newUriPermissionOwner(String name) {
7837         enforceNotIsolatedCaller("newUriPermissionOwner");
7838         synchronized(this) {
7839             UriPermissionOwner owner = new UriPermissionOwner(this, name);
7840             return owner.getExternalTokenLocked();
7841         }
7842     }
7843
7844     /**
7845      * @param uri This uri must NOT contain an embedded userId.
7846      * @param sourceUserId The userId in which the uri is to be resolved.
7847      * @param targetUserId The userId of the app that receives the grant.
7848      */
7849     @Override
7850     public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
7851             final int modeFlags, int sourceUserId, int targetUserId) {
7852         targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
7853                 targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null);
7854         synchronized(this) {
7855             UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7856             if (owner == null) {
7857                 throw new IllegalArgumentException("Unknown owner: " + token);
7858             }
7859             if (fromUid != Binder.getCallingUid()) {
7860                 if (Binder.getCallingUid() != Process.myUid()) {
7861                     // Only system code can grant URI permissions on behalf
7862                     // of other users.
7863                     throw new SecurityException("nice try");
7864                 }
7865             }
7866             if (targetPkg == null) {
7867                 throw new IllegalArgumentException("null target");
7868             }
7869             if (uri == null) {
7870                 throw new IllegalArgumentException("null uri");
7871             }
7872
7873             grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
7874                     modeFlags, owner, targetUserId);
7875         }
7876     }
7877
7878     /**
7879      * @param uri This uri must NOT contain an embedded userId.
7880      * @param userId The userId in which the uri is to be resolved.
7881      */
7882     @Override
7883     public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
7884         synchronized(this) {
7885             UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7886             if (owner == null) {
7887                 throw new IllegalArgumentException("Unknown owner: " + token);
7888             }
7889
7890             if (uri == null) {
7891                 owner.removeUriPermissionsLocked(mode);
7892             } else {
7893                 owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
7894             }
7895         }
7896     }
7897
7898     private void schedulePersistUriGrants() {
7899         if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
7900             mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
7901                     10 * DateUtils.SECOND_IN_MILLIS);
7902         }
7903     }
7904
7905     private void writeGrantedUriPermissions() {
7906         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
7907
7908         // Snapshot permissions so we can persist without lock
7909         ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
7910         synchronized (this) {
7911             final int size = mGrantedUriPermissions.size();
7912             for (int i = 0; i < size; i++) {
7913                 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7914                 for (UriPermission perm : perms.values()) {
7915                     if (perm.persistedModeFlags != 0) {
7916                         persist.add(perm.snapshot());
7917                     }
7918                 }
7919             }
7920         }
7921
7922         FileOutputStream fos = null;
7923         try {
7924             fos = mGrantFile.startWrite();
7925
7926             XmlSerializer out = new FastXmlSerializer();
7927             out.setOutput(fos, StandardCharsets.UTF_8.name());
7928             out.startDocument(null, true);
7929             out.startTag(null, TAG_URI_GRANTS);
7930             for (UriPermission.Snapshot perm : persist) {
7931                 out.startTag(null, TAG_URI_GRANT);
7932                 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
7933                 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
7934                 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
7935                 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
7936                 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
7937                 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
7938                 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
7939                 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
7940                 out.endTag(null, TAG_URI_GRANT);
7941             }
7942             out.endTag(null, TAG_URI_GRANTS);
7943             out.endDocument();
7944
7945             mGrantFile.finishWrite(fos);
7946         } catch (IOException e) {
7947             if (fos != null) {
7948                 mGrantFile.failWrite(fos);
7949             }
7950         }
7951     }
7952
7953     private void readGrantedUriPermissionsLocked() {
7954         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
7955
7956         final long now = System.currentTimeMillis();
7957
7958         FileInputStream fis = null;
7959         try {
7960             fis = mGrantFile.openRead();
7961             final XmlPullParser in = Xml.newPullParser();
7962             in.setInput(fis, StandardCharsets.UTF_8.name());
7963
7964             int type;
7965             while ((type = in.next()) != END_DOCUMENT) {
7966                 final String tag = in.getName();
7967                 if (type == START_TAG) {
7968                     if (TAG_URI_GRANT.equals(tag)) {
7969                         final int sourceUserId;
7970                         final int targetUserId;
7971                         final int userHandle = readIntAttribute(in,
7972                                 ATTR_USER_HANDLE, UserHandle.USER_NULL);
7973                         if (userHandle != UserHandle.USER_NULL) {
7974                             // For backwards compatibility.
7975                             sourceUserId = userHandle;
7976                             targetUserId = userHandle;
7977                         } else {
7978                             sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
7979                             targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
7980                         }
7981                         final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
7982                         final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
7983                         final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
7984                         final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
7985                         final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
7986                         final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
7987
7988                         // Sanity check that provider still belongs to source package
7989                         final ProviderInfo pi = getProviderInfoLocked(
7990                                 uri.getAuthority(), sourceUserId);
7991                         if (pi != null && sourcePkg.equals(pi.packageName)) {
7992                             int targetUid = -1;
7993                             try {
7994                                 targetUid = AppGlobals.getPackageManager()
7995                                         .getPackageUid(targetPkg, targetUserId);
7996                             } catch (RemoteException e) {
7997                             }
7998                             if (targetUid != -1) {
7999                                 final UriPermission perm = findOrCreateUriPermissionLocked(
8000                                         sourcePkg, targetPkg, targetUid,
8001                                         new GrantUri(sourceUserId, uri, prefix));
8002                                 perm.initPersistedModes(modeFlags, createdTime);
8003                             }
8004                         } else {
8005                             Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
8006                                     + " but instead found " + pi);
8007                         }
8008                     }
8009                 }
8010             }
8011         } catch (FileNotFoundException e) {
8012             // Missing grants is okay
8013         } catch (IOException e) {
8014             Slog.wtf(TAG, "Failed reading Uri grants", e);
8015         } catch (XmlPullParserException e) {
8016             Slog.wtf(TAG, "Failed reading Uri grants", e);
8017         } finally {
8018             IoUtils.closeQuietly(fis);
8019         }
8020     }
8021
8022     /**
8023      * @param uri This uri must NOT contain an embedded userId.
8024      * @param userId The userId in which the uri is to be resolved.
8025      */
8026     @Override
8027     public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8028         enforceNotIsolatedCaller("takePersistableUriPermission");
8029
8030         Preconditions.checkFlagsArgument(modeFlags,
8031                 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8032
8033         synchronized (this) {
8034             final int callingUid = Binder.getCallingUid();
8035             boolean persistChanged = false;
8036             GrantUri grantUri = new GrantUri(userId, uri, false);
8037
8038             UriPermission exactPerm = findUriPermissionLocked(callingUid,
8039                     new GrantUri(userId, uri, false));
8040             UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8041                     new GrantUri(userId, uri, true));
8042
8043             final boolean exactValid = (exactPerm != null)
8044                     && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
8045             final boolean prefixValid = (prefixPerm != null)
8046                     && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
8047
8048             if (!(exactValid || prefixValid)) {
8049                 throw new SecurityException("No persistable permission grants found for UID "
8050                         + callingUid + " and Uri " + grantUri.toSafeString());
8051             }
8052
8053             if (exactValid) {
8054                 persistChanged |= exactPerm.takePersistableModes(modeFlags);
8055             }
8056             if (prefixValid) {
8057                 persistChanged |= prefixPerm.takePersistableModes(modeFlags);
8058             }
8059
8060             persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
8061
8062             if (persistChanged) {
8063                 schedulePersistUriGrants();
8064             }
8065         }
8066     }
8067
8068     /**
8069      * @param uri This uri must NOT contain an embedded userId.
8070      * @param userId The userId in which the uri is to be resolved.
8071      */
8072     @Override
8073     public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8074         enforceNotIsolatedCaller("releasePersistableUriPermission");
8075
8076         Preconditions.checkFlagsArgument(modeFlags,
8077                 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8078
8079         synchronized (this) {
8080             final int callingUid = Binder.getCallingUid();
8081             boolean persistChanged = false;
8082
8083             UriPermission exactPerm = findUriPermissionLocked(callingUid,
8084                     new GrantUri(userId, uri, false));
8085             UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8086                     new GrantUri(userId, uri, true));
8087             if (exactPerm == null && prefixPerm == null) {
8088                 throw new SecurityException("No permission grants found for UID " + callingUid
8089                         + " and Uri " + uri.toSafeString());
8090             }
8091
8092             if (exactPerm != null) {
8093                 persistChanged |= exactPerm.releasePersistableModes(modeFlags);
8094                 removeUriPermissionIfNeededLocked(exactPerm);
8095             }
8096             if (prefixPerm != null) {
8097                 persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
8098                 removeUriPermissionIfNeededLocked(prefixPerm);
8099             }
8100
8101             if (persistChanged) {
8102                 schedulePersistUriGrants();
8103             }
8104         }
8105     }
8106
8107     /**
8108      * Prune any older {@link UriPermission} for the given UID until outstanding
8109      * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
8110      *
8111      * @return if any mutations occured that require persisting.
8112      */
8113     private boolean maybePrunePersistedUriGrantsLocked(int uid) {
8114         final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8115         if (perms == null) return false;
8116         if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
8117
8118         final ArrayList<UriPermission> persisted = Lists.newArrayList();
8119         for (UriPermission perm : perms.values()) {
8120             if (perm.persistedModeFlags != 0) {
8121                 persisted.add(perm);
8122             }
8123         }
8124
8125         final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
8126         if (trimCount <= 0) return false;
8127
8128         Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
8129         for (int i = 0; i < trimCount; i++) {
8130             final UriPermission perm = persisted.get(i);
8131
8132             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8133                     "Trimming grant created at " + perm.persistedCreateTime);
8134
8135             perm.releasePersistableModes(~0);
8136             removeUriPermissionIfNeededLocked(perm);
8137         }
8138
8139         return true;
8140     }
8141
8142     @Override
8143     public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8144             String packageName, boolean incoming) {
8145         enforceNotIsolatedCaller("getPersistedUriPermissions");
8146         Preconditions.checkNotNull(packageName, "packageName");
8147
8148         final int callingUid = Binder.getCallingUid();
8149         final IPackageManager pm = AppGlobals.getPackageManager();
8150         try {
8151             final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
8152             if (packageUid != callingUid) {
8153                 throw new SecurityException(
8154                         "Package " + packageName + " does not belong to calling UID " + callingUid);
8155             }
8156         } catch (RemoteException e) {
8157             throw new SecurityException("Failed to verify package name ownership");
8158         }
8159
8160         final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8161         synchronized (this) {
8162             if (incoming) {
8163                 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8164                         callingUid);
8165                 if (perms == null) {
8166                     Slog.w(TAG, "No permission grants found for " + packageName);
8167                 } else {
8168                     for (UriPermission perm : perms.values()) {
8169                         if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8170                             result.add(perm.buildPersistedPublicApiObject());
8171                         }
8172                     }
8173                 }
8174             } else {
8175                 final int size = mGrantedUriPermissions.size();
8176                 for (int i = 0; i < size; i++) {
8177                     final ArrayMap<GrantUri, UriPermission> perms =
8178                             mGrantedUriPermissions.valueAt(i);
8179                     for (UriPermission perm : perms.values()) {
8180                         if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8181                             result.add(perm.buildPersistedPublicApiObject());
8182                         }
8183                     }
8184                 }
8185             }
8186         }
8187         return new ParceledListSlice<android.content.UriPermission>(result);
8188     }
8189
8190     @Override
8191     public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
8192         synchronized (this) {
8193             ProcessRecord app =
8194                 who != null ? getRecordForAppLocked(who) : null;
8195             if (app == null) return;
8196
8197             Message msg = Message.obtain();
8198             msg.what = WAIT_FOR_DEBUGGER_MSG;
8199             msg.obj = app;
8200             msg.arg1 = waiting ? 1 : 0;
8201             mUiHandler.sendMessage(msg);
8202         }
8203     }
8204
8205     @Override
8206     public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
8207         final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
8208         final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
8209         outInfo.availMem = Process.getFreeMemory();
8210         outInfo.totalMem = Process.getTotalMemory();
8211         outInfo.threshold = homeAppMem;
8212         outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
8213         outInfo.hiddenAppThreshold = cachedAppMem;
8214         outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
8215                 ProcessList.SERVICE_ADJ);
8216         outInfo.visibleAppThreshold = mProcessList.getMemLevel(
8217                 ProcessList.VISIBLE_APP_ADJ);
8218         outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
8219                 ProcessList.FOREGROUND_APP_ADJ);
8220     }
8221
8222     // =========================================================
8223     // TASK MANAGEMENT
8224     // =========================================================
8225
8226     @Override
8227     public List<IAppTask> getAppTasks(String callingPackage) {
8228         int callingUid = Binder.getCallingUid();
8229         long ident = Binder.clearCallingIdentity();
8230
8231         synchronized(this) {
8232             ArrayList<IAppTask> list = new ArrayList<IAppTask>();
8233             try {
8234                 if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
8235
8236                 final int N = mRecentTasks.size();
8237                 for (int i = 0; i < N; i++) {
8238                     TaskRecord tr = mRecentTasks.get(i);
8239                     // Skip tasks that do not match the caller.  We don't need to verify
8240                     // callingPackage, because we are also limiting to callingUid and know
8241                     // that will limit to the correct security sandbox.
8242                     if (tr.effectiveUid != callingUid) {
8243                         continue;
8244                     }
8245                     Intent intent = tr.getBaseIntent();
8246                     if (intent == null ||
8247                             !callingPackage.equals(intent.getComponent().getPackageName())) {
8248                         continue;
8249                     }
8250                     ActivityManager.RecentTaskInfo taskInfo =
8251                             createRecentTaskInfoFromTaskRecord(tr);
8252                     AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8253                     list.add(taskImpl);
8254                 }
8255             } finally {
8256                 Binder.restoreCallingIdentity(ident);
8257             }
8258             return list;
8259         }
8260     }
8261
8262     @Override
8263     public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8264         final int callingUid = Binder.getCallingUid();
8265         ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8266
8267         synchronized(this) {
8268             if (DEBUG_ALL) Slog.v(
8269                 TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8270
8271             final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
8272                     callingUid);
8273
8274             // TODO: Improve with MRU list from all ActivityStacks.
8275             mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8276         }
8277
8278         return list;
8279     }
8280
8281     /**
8282      * Creates a new RecentTaskInfo from a TaskRecord.
8283      */
8284     private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8285         // Update the task description to reflect any changes in the task stack
8286         tr.updateTaskDescription();
8287
8288         // Compose the recent task info
8289         ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8290         rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
8291         rti.persistentId = tr.taskId;
8292         rti.baseIntent = new Intent(tr.getBaseIntent());
8293         rti.origActivity = tr.origActivity;
8294         rti.description = tr.lastDescription;
8295         rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8296         rti.userId = tr.userId;
8297         rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8298         rti.firstActiveTime = tr.firstActiveTime;
8299         rti.lastActiveTime = tr.lastActiveTime;
8300         rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8301         rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8302         rti.numActivities = 0;
8303
8304         ActivityRecord base = null;
8305         ActivityRecord top = null;
8306         ActivityRecord tmp;
8307
8308         for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
8309             tmp = tr.mActivities.get(i);
8310             if (tmp.finishing) {
8311                 continue;
8312             }
8313             base = tmp;
8314             if (top == null || (top.state == ActivityState.INITIALIZING)) {
8315                 top = base;
8316             }
8317             rti.numActivities++;
8318         }
8319
8320         rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
8321         rti.topActivity = (top != null) ? top.intent.getComponent() : null;
8322
8323         return rti;
8324     }
8325
8326     private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
8327         boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
8328                 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
8329         if (!allowed) {
8330             if (checkPermission(android.Manifest.permission.GET_TASKS,
8331                     callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
8332                 // Temporary compatibility: some existing apps on the system image may
8333                 // still be requesting the old permission and not switched to the new
8334                 // one; if so, we'll still allow them full access.  This means we need
8335                 // to see if they are holding the old permission and are a system app.
8336                 try {
8337                     if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
8338                         allowed = true;
8339                         if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
8340                                 + " is using old GET_TASKS but privileged; allowing");
8341                     }
8342                 } catch (RemoteException e) {
8343                 }
8344             }
8345         }
8346         if (!allowed) {
8347             if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
8348                     + " does not hold REAL_GET_TASKS; limiting output");
8349         }
8350         return allowed;
8351     }
8352
8353     @Override
8354     public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8355         final int callingUid = Binder.getCallingUid();
8356         userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8357                 false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8358
8359         final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8360         final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8361         synchronized (this) {
8362             final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
8363                     callingUid);
8364             final boolean detailed = checkCallingPermission(
8365                     android.Manifest.permission.GET_DETAILED_TASKS)
8366                     == PackageManager.PERMISSION_GRANTED;
8367
8368             final int recentsCount = mRecentTasks.size();
8369             ArrayList<ActivityManager.RecentTaskInfo> res =
8370                     new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
8371
8372             final Set<Integer> includedUsers;
8373             if (includeProfiles) {
8374                 includedUsers = getProfileIdsLocked(userId);
8375             } else {
8376                 includedUsers = new HashSet<>();
8377             }
8378             includedUsers.add(Integer.valueOf(userId));
8379
8380             for (int i = 0; i < recentsCount && maxNum > 0; i++) {
8381                 TaskRecord tr = mRecentTasks.get(i);
8382                 // Only add calling user or related users recent tasks
8383                 if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
8384                     if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
8385                     continue;
8386                 }
8387
8388                 // Return the entry if desired by the caller.  We always return
8389                 // the first entry, because callers always expect this to be the
8390                 // foreground app.  We may filter others if the caller has
8391                 // not supplied RECENT_WITH_EXCLUDED and there is some reason
8392                 // we should exclude the entry.
8393
8394                 if (i == 0
8395                         || withExcluded
8396                         || (tr.intent == null)
8397                         || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
8398                                 == 0)) {
8399                     if (!allowed) {
8400                         // If the caller doesn't have the GET_TASKS permission, then only
8401                         // allow them to see a small subset of tasks -- their own and home.
8402                         if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
8403                             if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
8404                             continue;
8405                         }
8406                     }
8407                     if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
8408                         if (tr.stack != null && tr.stack.isHomeStack()) {
8409                             if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8410                                     "Skipping, home stack task: " + tr);
8411                             continue;
8412                         }
8413                     }
8414                     if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
8415                         // Don't include auto remove tasks that are finished or finishing.
8416                         if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8417                                 "Skipping, auto-remove without activity: " + tr);
8418                         continue;
8419                     }
8420                     if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
8421                             && !tr.isAvailable) {
8422                         if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8423                                 "Skipping, unavail real act: " + tr);
8424                         continue;
8425                     }
8426
8427                     ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
8428                     if (!detailed) {
8429                         rti.baseIntent.replaceExtras((Bundle)null);
8430                     }
8431
8432                     res.add(rti);
8433                     maxNum--;
8434                 }
8435             }
8436             return res;
8437         }
8438     }
8439
8440     @Override
8441     public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
8442         synchronized (this) {
8443             enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
8444                     "getTaskThumbnail()");
8445             TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(id, false);
8446             if (tr != null) {
8447                 return tr.getTaskThumbnailLocked();
8448             }
8449         }
8450         return null;
8451     }
8452
8453     @Override
8454     public int addAppTask(IBinder activityToken, Intent intent,
8455             ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
8456         final int callingUid = Binder.getCallingUid();
8457         final long callingIdent = Binder.clearCallingIdentity();
8458
8459         try {
8460             synchronized (this) {
8461                 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8462                 if (r == null) {
8463                     throw new IllegalArgumentException("Activity does not exist; token="
8464                             + activityToken);
8465                 }
8466                 ComponentName comp = intent.getComponent();
8467                 if (comp == null) {
8468                     throw new IllegalArgumentException("Intent " + intent
8469                             + " must specify explicit component");
8470                 }
8471                 if (thumbnail.getWidth() != mThumbnailWidth
8472                         || thumbnail.getHeight() != mThumbnailHeight) {
8473                     throw new IllegalArgumentException("Bad thumbnail size: got "
8474                             + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
8475                             + mThumbnailWidth + "x" + mThumbnailHeight);
8476                 }
8477                 if (intent.getSelector() != null) {
8478                     intent.setSelector(null);
8479                 }
8480                 if (intent.getSourceBounds() != null) {
8481                     intent.setSourceBounds(null);
8482                 }
8483                 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
8484                     if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
8485                         // The caller has added this as an auto-remove task...  that makes no
8486                         // sense, so turn off auto-remove.
8487                         intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
8488                     }
8489                 } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
8490                     // Must be a new task.
8491                     intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8492                 }
8493                 if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
8494                     mLastAddedTaskActivity = null;
8495                 }
8496                 ActivityInfo ainfo = mLastAddedTaskActivity;
8497                 if (ainfo == null) {
8498                     ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
8499                             comp, 0, UserHandle.getUserId(callingUid));
8500                     if (ainfo.applicationInfo.uid != callingUid) {
8501                         throw new SecurityException(
8502                                 "Can't add task for another application: target uid="
8503                                 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
8504                     }
8505                 }
8506
8507                 TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo,
8508                         intent, description);
8509
8510                 int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
8511                 if (trimIdx >= 0) {
8512                     // If this would have caused a trim, then we'll abort because that
8513                     // means it would be added at the end of the list but then just removed.
8514                     return INVALID_TASK_ID;
8515                 }
8516
8517                 final int N = mRecentTasks.size();
8518                 if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
8519                     final TaskRecord tr = mRecentTasks.remove(N - 1);
8520                     tr.removedFromRecents();
8521                 }
8522
8523                 task.inRecents = true;
8524                 mRecentTasks.add(task);
8525                 r.task.stack.addTask(task, false, false);
8526
8527                 task.setLastThumbnail(thumbnail);
8528                 task.freeLastThumbnail();
8529
8530                 return task.taskId;
8531             }
8532         } finally {
8533             Binder.restoreCallingIdentity(callingIdent);
8534         }
8535     }
8536
8537     @Override
8538     public Point getAppTaskThumbnailSize() {
8539         synchronized (this) {
8540             return new Point(mThumbnailWidth,  mThumbnailHeight);
8541         }
8542     }
8543
8544     @Override
8545     public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
8546         synchronized (this) {
8547             ActivityRecord r = ActivityRecord.isInStackLocked(token);
8548             if (r != null) {
8549                 r.setTaskDescription(td);
8550                 r.task.updateTaskDescription();
8551             }
8552         }
8553     }
8554
8555     @Override
8556     public void setTaskResizeable(int taskId, boolean resizeable) {
8557         synchronized (this) {
8558             TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId, false);
8559             if (task == null) {
8560                 Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
8561                 return;
8562             }
8563             if (task.mResizeable != resizeable) {
8564                 task.mResizeable = resizeable;
8565                 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
8566                 mStackSupervisor.resumeTopActivitiesLocked();
8567             }
8568         }
8569     }
8570
8571     @Override
8572     public void resizeTask(int taskId, Rect bounds) {
8573         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8574                 "resizeTask()");
8575         long ident = Binder.clearCallingIdentity();
8576         try {
8577             synchronized (this) {
8578                 TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8579                 if (task == null) {
8580                     Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
8581                     return;
8582                 }
8583                 mStackSupervisor.resizeTaskLocked(task, bounds);
8584             }
8585         } finally {
8586             Binder.restoreCallingIdentity(ident);
8587         }
8588     }
8589
8590     @Override
8591     public Bitmap getTaskDescriptionIcon(String filename) {
8592         if (!FileUtils.isValidExtFilename(filename)
8593                 || !filename.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
8594             throw new IllegalArgumentException("Bad filename: " + filename);
8595         }
8596         return mTaskPersister.getTaskDescriptionIcon(filename);
8597     }
8598
8599     @Override
8600     public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
8601             throws RemoteException {
8602         if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
8603                 opts.getCustomInPlaceResId() == 0) {
8604             throw new IllegalArgumentException("Expected in-place ActivityOption " +
8605                     "with valid animation");
8606         }
8607         mWindowManager.prepareAppTransition(AppTransition.TRANSIT_TASK_IN_PLACE, false);
8608         mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
8609                 opts.getCustomInPlaceResId());
8610         mWindowManager.executeAppTransition();
8611     }
8612
8613     private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess) {
8614         mRecentTasks.remove(tr);
8615         tr.removedFromRecents();
8616         ComponentName component = tr.getBaseIntent().getComponent();
8617         if (component == null) {
8618             Slog.w(TAG, "No component for base intent of task: " + tr);
8619             return;
8620         }
8621
8622         // Find any running services associated with this app and stop if needed.
8623         mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
8624
8625         if (!killProcess) {
8626             return;
8627         }
8628
8629         // Determine if the process(es) for this task should be killed.
8630         final String pkg = component.getPackageName();
8631         ArrayList<ProcessRecord> procsToKill = new ArrayList<>();
8632         ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
8633         for (int i = 0; i < pmap.size(); i++) {
8634
8635             SparseArray<ProcessRecord> uids = pmap.valueAt(i);
8636             for (int j = 0; j < uids.size(); j++) {
8637                 ProcessRecord proc = uids.valueAt(j);
8638                 if (proc.userId != tr.userId) {
8639                     // Don't kill process for a different user.
8640                     continue;
8641                 }
8642                 if (proc == mHomeProcess) {
8643                     // Don't kill the home process along with tasks from the same package.
8644                     continue;
8645                 }
8646                 if (!proc.pkgList.containsKey(pkg)) {
8647                     // Don't kill process that is not associated with this task.
8648                     continue;
8649                 }
8650
8651                 for (int k = 0; k < proc.activities.size(); k++) {
8652                     TaskRecord otherTask = proc.activities.get(k).task;
8653                     if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
8654                         // Don't kill process(es) that has an activity in a different task that is
8655                         // also in recents.
8656                         return;
8657                     }
8658                 }
8659
8660                 if (proc.foregroundServices) {
8661                     // Don't kill process(es) with foreground service.
8662                     return;
8663                 }
8664
8665                 // Add process to kill list.
8666                 procsToKill.add(proc);
8667             }
8668         }
8669
8670         // Kill the running processes.
8671         for (int i = 0; i < procsToKill.size(); i++) {
8672             ProcessRecord pr = procsToKill.get(i);
8673             if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
8674                     && pr.curReceiver == null) {
8675                 pr.kill("remove task", true);
8676             } else {
8677                 // We delay killing processes that are not in the background or running a receiver.
8678                 pr.waitingToKill = "remove task";
8679             }
8680         }
8681     }
8682
8683     private void removeTasksByPackageNameLocked(String packageName, int userId) {
8684         // Remove all tasks with activities in the specified package from the list of recent tasks
8685         for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
8686             TaskRecord tr = mRecentTasks.get(i);
8687             if (tr.userId != userId) continue;
8688
8689             ComponentName cn = tr.intent.getComponent();
8690             if (cn != null && cn.getPackageName().equals(packageName)) {
8691                 // If the package name matches, remove the task.
8692                 removeTaskByIdLocked(tr.taskId, true);
8693             }
8694         }
8695     }
8696
8697     private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
8698             int userId) {
8699
8700         for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
8701             TaskRecord tr = mRecentTasks.get(i);
8702             if (userId != UserHandle.USER_ALL && tr.userId != userId) {
8703                 continue;
8704             }
8705
8706             ComponentName cn = tr.intent.getComponent();
8707             final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
8708                     && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
8709             if (sameComponent) {
8710                 removeTaskByIdLocked(tr.taskId, false);
8711             }
8712         }
8713     }
8714
8715     /**
8716      * Removes the task with the specified task id.
8717      *
8718      * @param taskId Identifier of the task to be removed.
8719      * @param killProcess Kill any process associated with the task if possible.
8720      * @return Returns true if the given task was found and removed.
8721      */
8722     private boolean removeTaskByIdLocked(int taskId, boolean killProcess) {
8723         TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(taskId, false);
8724         if (tr != null) {
8725             tr.removeTaskActivitiesLocked();
8726             cleanUpRemovedTaskLocked(tr, killProcess);
8727             if (tr.isPersistable) {
8728                 notifyTaskPersisterLocked(null, true);
8729             }
8730             return true;
8731         }
8732         Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
8733         return false;
8734     }
8735
8736     @Override
8737     public boolean removeTask(int taskId) {
8738         synchronized (this) {
8739             enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
8740                     "removeTask()");
8741             long ident = Binder.clearCallingIdentity();
8742             try {
8743                 return removeTaskByIdLocked(taskId, true);
8744             } finally {
8745                 Binder.restoreCallingIdentity(ident);
8746             }
8747         }
8748     }
8749
8750     /**
8751      * TODO: Add mController hook
8752      */
8753     @Override
8754     public void moveTaskToFront(int taskId, int flags, Bundle options) {
8755         enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
8756
8757         if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
8758         synchronized(this) {
8759             moveTaskToFrontLocked(taskId, flags, options);
8760         }
8761     }
8762
8763     void moveTaskToFrontLocked(int taskId, int flags, Bundle options) {
8764         if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8765                 Binder.getCallingUid(), -1, -1, "Task to front")) {
8766             ActivityOptions.abort(options);
8767             return;
8768         }
8769         final long origId = Binder.clearCallingIdentity();
8770         try {
8771             final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8772             if (task == null) {
8773                 Slog.d(TAG, "Could not find task for id: "+ taskId);
8774                 return;
8775             }
8776             if (mStackSupervisor.isLockTaskModeViolation(task)) {
8777                 mStackSupervisor.showLockTaskToast();
8778                 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
8779                 return;
8780             }
8781             final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
8782             if (prev != null && prev.isRecentsActivity()) {
8783                 task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
8784             }
8785             mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront");
8786         } finally {
8787             Binder.restoreCallingIdentity(origId);
8788         }
8789         ActivityOptions.abort(options);
8790     }
8791
8792     /**
8793      * Moves an activity, and all of the other activities within the same task, to the bottom
8794      * of the history stack.  The activity's order within the task is unchanged.
8795      *
8796      * @param token A reference to the activity we wish to move
8797      * @param nonRoot If false then this only works if the activity is the root
8798      *                of a task; if true it will work for any activity in a task.
8799      * @return Returns true if the move completed, false if not.
8800      */
8801     @Override
8802     public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
8803         enforceNotIsolatedCaller("moveActivityTaskToBack");
8804         synchronized(this) {
8805             final long origId = Binder.clearCallingIdentity();
8806             try {
8807                 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
8808                 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8809                 if (task != null) {
8810                     if (mStackSupervisor.isLockedTask(task)) {
8811                         mStackSupervisor.showLockTaskToast();
8812                         return false;
8813                     }
8814                     return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
8815                 }
8816             } finally {
8817                 Binder.restoreCallingIdentity(origId);
8818             }
8819         }
8820         return false;
8821     }
8822
8823     @Override
8824     public void moveTaskBackwards(int task) {
8825         enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8826                 "moveTaskBackwards()");
8827
8828         synchronized(this) {
8829             if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8830                     Binder.getCallingUid(), -1, -1, "Task backwards")) {
8831                 return;
8832             }
8833             final long origId = Binder.clearCallingIdentity();
8834             moveTaskBackwardsLocked(task);
8835             Binder.restoreCallingIdentity(origId);
8836         }
8837     }
8838
8839     private final void moveTaskBackwardsLocked(int task) {
8840         Slog.e(TAG, "moveTaskBackwards not yet implemented!");
8841     }
8842
8843     @Override
8844     public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
8845             IActivityContainerCallback callback) throws RemoteException {
8846         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8847                 "createActivityContainer()");
8848         synchronized (this) {
8849             if (parentActivityToken == null) {
8850                 throw new IllegalArgumentException("parent token must not be null");
8851             }
8852             ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
8853             if (r == null) {
8854                 return null;
8855             }
8856             if (callback == null) {
8857                 throw new IllegalArgumentException("callback must not be null");
8858             }
8859             return mStackSupervisor.createVirtualActivityContainer(r, callback);
8860         }
8861     }
8862
8863     @Override
8864     public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
8865         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8866                 "deleteActivityContainer()");
8867         synchronized (this) {
8868             mStackSupervisor.deleteActivityContainer(container);
8869         }
8870     }
8871
8872     @Override
8873     public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
8874         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8875                 "createStackOnDisplay()");
8876         synchronized (this) {
8877             final int stackId = mStackSupervisor.getNextStackId();
8878             final ActivityStack stack = mStackSupervisor.createStackOnDisplay(stackId, displayId);
8879             if (stack == null) {
8880                 return null;
8881             }
8882             return stack.mActivityContainer;
8883         }
8884     }
8885
8886     @Override
8887     public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
8888         synchronized (this) {
8889             ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
8890             if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
8891                 return stack.mActivityContainer.getDisplayId();
8892             }
8893             return Display.DEFAULT_DISPLAY;
8894         }
8895     }
8896
8897     @Override
8898     public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
8899         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8900                 "moveTaskToStack()");
8901         if (stackId == HOME_STACK_ID) {
8902             Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
8903                     new RuntimeException("here").fillInStackTrace());
8904         }
8905         synchronized (this) {
8906             long ident = Binder.clearCallingIdentity();
8907             try {
8908                 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
8909                         + " to stackId=" + stackId + " toTop=" + toTop);
8910                 mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop);
8911             } finally {
8912                 Binder.restoreCallingIdentity(ident);
8913             }
8914         }
8915     }
8916
8917     @Override
8918     public void resizeStack(int stackId, Rect bounds) {
8919         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8920                 "resizeStack()");
8921         long ident = Binder.clearCallingIdentity();
8922         try {
8923             synchronized (this) {
8924                 mStackSupervisor.resizeStackLocked(stackId, bounds);
8925             }
8926         } finally {
8927             Binder.restoreCallingIdentity(ident);
8928         }
8929     }
8930
8931     @Override
8932     public List<StackInfo> getAllStackInfos() {
8933         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8934                 "getAllStackInfos()");
8935         long ident = Binder.clearCallingIdentity();
8936         try {
8937             synchronized (this) {
8938                 return mStackSupervisor.getAllStackInfosLocked();
8939             }
8940         } finally {
8941             Binder.restoreCallingIdentity(ident);
8942         }
8943     }
8944
8945     @Override
8946     public StackInfo getStackInfo(int stackId) {
8947         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8948                 "getStackInfo()");
8949         long ident = Binder.clearCallingIdentity();
8950         try {
8951             synchronized (this) {
8952                 return mStackSupervisor.getStackInfoLocked(stackId);
8953             }
8954         } finally {
8955             Binder.restoreCallingIdentity(ident);
8956         }
8957     }
8958
8959     @Override
8960     public boolean isInHomeStack(int taskId) {
8961         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8962                 "getStackInfo()");
8963         long ident = Binder.clearCallingIdentity();
8964         try {
8965             synchronized (this) {
8966                 TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(taskId, false);
8967                 return tr != null && tr.stack != null && tr.stack.isHomeStack();
8968             }
8969         } finally {
8970             Binder.restoreCallingIdentity(ident);
8971         }
8972     }
8973
8974     @Override
8975     public int getTaskForActivity(IBinder token, boolean onlyRoot) {
8976         synchronized(this) {
8977             return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
8978         }
8979     }
8980
8981     @Override
8982     public void updateDeviceOwner(String packageName) {
8983         final int callingUid = Binder.getCallingUid();
8984         if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
8985             throw new SecurityException("updateDeviceOwner called from non-system process");
8986         }
8987         synchronized (this) {
8988             mDeviceOwnerName = packageName;
8989         }
8990     }
8991
8992     @Override
8993     public void updateLockTaskPackages(int userId, String[] packages) {
8994         final int callingUid = Binder.getCallingUid();
8995         if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
8996             throw new SecurityException("updateLockTaskPackage called from non-system process");
8997         }
8998         synchronized (this) {
8999             if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
9000                     Arrays.toString(packages));
9001             mLockTaskPackages.put(userId, packages);
9002             mStackSupervisor.onLockTaskPackagesUpdatedLocked();
9003         }
9004     }
9005
9006
9007     void startLockTaskModeLocked(TaskRecord task) {
9008         if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
9009         if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
9010             return;
9011         }
9012
9013         // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
9014         // is initiated by system after the pinning request was shown and locked mode is initiated
9015         // by an authorized app directly
9016         final int callingUid = Binder.getCallingUid();
9017         boolean isSystemInitiated = callingUid == Process.SYSTEM_UID;
9018         long ident = Binder.clearCallingIdentity();
9019         try {
9020             final ActivityStack stack = mStackSupervisor.getFocusedStack();
9021             if (!isSystemInitiated) {
9022                 task.mLockTaskUid = callingUid;
9023                 if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
9024                     // startLockTask() called by app and task mode is lockTaskModeDefault.
9025                     if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
9026                     StatusBarManagerInternal statusBarManager =
9027                             LocalServices.getService(StatusBarManagerInternal.class);
9028                     if (statusBarManager != null) {
9029                         statusBarManager.showScreenPinningRequest();
9030                     }
9031                     return;
9032                 }
9033
9034                 if (stack == null || task != stack.topTask()) {
9035                     throw new IllegalArgumentException("Invalid task, not in foreground");
9036                 }
9037             }
9038             if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
9039                     "Locking fully");
9040             mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
9041                     ActivityManager.LOCK_TASK_MODE_PINNED :
9042                     ActivityManager.LOCK_TASK_MODE_LOCKED,
9043                     "startLockTask", true);
9044         } finally {
9045             Binder.restoreCallingIdentity(ident);
9046         }
9047     }
9048
9049     @Override
9050     public void startLockTaskMode(int taskId) {
9051         synchronized (this) {
9052             final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9053             if (task != null) {
9054                 startLockTaskModeLocked(task);
9055             }
9056         }
9057     }
9058
9059     @Override
9060     public void startLockTaskMode(IBinder token) {
9061         synchronized (this) {
9062             final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9063             if (r == null) {
9064                 return;
9065             }
9066             final TaskRecord task = r.task;
9067             if (task != null) {
9068                 startLockTaskModeLocked(task);
9069             }
9070         }
9071     }
9072
9073     @Override
9074     public void startLockTaskModeOnCurrent() throws RemoteException {
9075         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9076                 "startLockTaskModeOnCurrent");
9077         long ident = Binder.clearCallingIdentity();
9078         try {
9079             synchronized (this) {
9080                 ActivityRecord r = mStackSupervisor.topRunningActivityLocked();
9081                 if (r != null) {
9082                     startLockTaskModeLocked(r.task);
9083                 }
9084             }
9085         } finally {
9086             Binder.restoreCallingIdentity(ident);
9087         }
9088     }
9089
9090     @Override
9091     public void stopLockTaskMode() {
9092         final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
9093         if (lockTask == null) {
9094             // Our work here is done.
9095             return;
9096         }
9097
9098         final int callingUid = Binder.getCallingUid();
9099         final int lockTaskUid = lockTask.mLockTaskUid;
9100         // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
9101         // It is possible lockTaskMode was started by the system process because
9102         // android:lockTaskMode is set to a locking value in the application manifest instead of
9103         // the app calling startLockTaskMode. In this case {@link TaskRecord.mLockTaskUid} will
9104         // be 0, so we compare the callingUid to the {@link TaskRecord.effectiveUid} instead.
9105         if (getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_LOCKED &&
9106                 callingUid != lockTaskUid
9107                 && (lockTaskUid != 0
9108                     || (lockTaskUid == 0 && callingUid != lockTask.effectiveUid))) {
9109             throw new SecurityException("Invalid uid, expected " + lockTaskUid
9110                     + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
9111         }
9112
9113         long ident = Binder.clearCallingIdentity();
9114         try {
9115             Log.d(TAG, "stopLockTaskMode");
9116             // Stop lock task
9117             synchronized (this) {
9118                 mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
9119                         "stopLockTask", true);
9120             }
9121         } finally {
9122             Binder.restoreCallingIdentity(ident);
9123         }
9124     }
9125
9126     @Override
9127     public void stopLockTaskModeOnCurrent() throws RemoteException {
9128         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9129                 "stopLockTaskModeOnCurrent");
9130         long ident = Binder.clearCallingIdentity();
9131         try {
9132             stopLockTaskMode();
9133         } finally {
9134             Binder.restoreCallingIdentity(ident);
9135         }
9136     }
9137
9138     @Override
9139     public boolean isInLockTaskMode() {
9140         return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
9141     }
9142
9143     @Override
9144     public int getLockTaskModeState() {
9145         synchronized (this) {
9146             return mStackSupervisor.getLockTaskModeState();
9147         }
9148     }
9149
9150     @Override
9151     public void showLockTaskEscapeMessage(IBinder token) {
9152         synchronized (this) {
9153             final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9154             if (r == null) {
9155                 return;
9156             }
9157             mStackSupervisor.showLockTaskEscapeMessageLocked(r.task);
9158         }
9159     }
9160
9161     // =========================================================
9162     // CONTENT PROVIDERS
9163     // =========================================================
9164
9165     private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
9166         List<ProviderInfo> providers = null;
9167         try {
9168             ParceledListSlice<ProviderInfo> slice = AppGlobals.getPackageManager().
9169                 queryContentProviders(app.processName, app.uid,
9170                         STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
9171             providers = slice != null ? slice.getList() : null;
9172         } catch (RemoteException ex) {
9173         }
9174         if (DEBUG_MU) Slog.v(TAG_MU,
9175                 "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
9176         int userId = app.userId;
9177         if (providers != null) {
9178             int N = providers.size();
9179             app.pubProviders.ensureCapacity(N + app.pubProviders.size());
9180             for (int i=0; i<N; i++) {
9181                 ProviderInfo cpi =
9182                     (ProviderInfo)providers.get(i);
9183                 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9184                         cpi.name, cpi.flags);
9185                 if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_OWNER) {
9186                     // This is a singleton provider, but a user besides the
9187                     // default user is asking to initialize a process it runs
9188                     // in...  well, no, it doesn't actually run in this process,
9189                     // it runs in the process of the default user.  Get rid of it.
9190                     providers.remove(i);
9191                     N--;
9192                     i--;
9193                     continue;
9194                 }
9195
9196                 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9197                 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
9198                 if (cpr == null) {
9199                     cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
9200                     mProviderMap.putProviderByClass(comp, cpr);
9201                 }
9202                 if (DEBUG_MU) Slog.v(TAG_MU,
9203                         "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
9204                 app.pubProviders.put(cpi.name, cpr);
9205                 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
9206                     // Don't add this if it is a platform component that is marked
9207                     // to run in multiple processes, because this is actually
9208                     // part of the framework so doesn't make sense to track as a
9209                     // separate apk in the process.
9210                     app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
9211                             mProcessStats);
9212                 }
9213                 ensurePackageDexOpt(cpi.applicationInfo.packageName);
9214             }
9215         }
9216         return providers;
9217     }
9218
9219     /**
9220      * Check if {@link ProcessRecord} has a possible chance at accessing the
9221      * given {@link ProviderInfo}. Final permission checking is always done
9222      * in {@link ContentProvider}.
9223      */
9224     private final String checkContentProviderPermissionLocked(
9225             ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
9226         final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
9227         final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
9228         boolean checkedGrants = false;
9229         if (checkUser) {
9230             // Looking for cross-user grants before enforcing the typical cross-users permissions
9231             int tmpTargetUserId = unsafeConvertIncomingUser(userId);
9232             if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
9233                 if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
9234                     return null;
9235                 }
9236                 checkedGrants = true;
9237             }
9238             userId = handleIncomingUser(callingPid, callingUid, userId,
9239                     false, ALLOW_NON_FULL,
9240                     "checkContentProviderPermissionLocked " + cpi.authority, null);
9241             if (userId != tmpTargetUserId) {
9242                 // When we actually went to determine the final targer user ID, this ended
9243                 // up different than our initial check for the authority.  This is because
9244                 // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
9245                 // SELF.  So we need to re-check the grants again.
9246                 checkedGrants = false;
9247             }
9248         }
9249         if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
9250                 cpi.applicationInfo.uid, cpi.exported)
9251                 == PackageManager.PERMISSION_GRANTED) {
9252             return null;
9253         }
9254         if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
9255                 cpi.applicationInfo.uid, cpi.exported)
9256                 == PackageManager.PERMISSION_GRANTED) {
9257             return null;
9258         }
9259
9260         PathPermission[] pps = cpi.pathPermissions;
9261         if (pps != null) {
9262             int i = pps.length;
9263             while (i > 0) {
9264                 i--;
9265                 PathPermission pp = pps[i];
9266                 String pprperm = pp.getReadPermission();
9267                 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
9268                         cpi.applicationInfo.uid, cpi.exported)
9269                         == PackageManager.PERMISSION_GRANTED) {
9270                     return null;
9271                 }
9272                 String ppwperm = pp.getWritePermission();
9273                 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
9274                         cpi.applicationInfo.uid, cpi.exported)
9275                         == PackageManager.PERMISSION_GRANTED) {
9276                     return null;
9277                 }
9278             }
9279         }
9280         if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
9281             return null;
9282         }
9283
9284         String msg;
9285         if (!cpi.exported) {
9286             msg = "Permission Denial: opening provider " + cpi.name
9287                     + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9288                     + ", uid=" + callingUid + ") that is not exported from uid "
9289                     + cpi.applicationInfo.uid;
9290         } else {
9291             msg = "Permission Denial: opening provider " + cpi.name
9292                     + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9293                     + ", uid=" + callingUid + ") requires "
9294                     + cpi.readPermission + " or " + cpi.writePermission;
9295         }
9296         Slog.w(TAG, msg);
9297         return msg;
9298     }
9299
9300     /**
9301      * Returns if the ContentProvider has granted a uri to callingUid
9302      */
9303     boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
9304         final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
9305         if (perms != null) {
9306             for (int i=perms.size()-1; i>=0; i--) {
9307                 GrantUri grantUri = perms.keyAt(i);
9308                 if (grantUri.sourceUserId == userId || !checkUser) {
9309                     if (matchesProvider(grantUri.uri, cpi)) {
9310                         return true;
9311                     }
9312                 }
9313             }
9314         }
9315         return false;
9316     }
9317
9318     /**
9319      * Returns true if the uri authority is one of the authorities specified in the provider.
9320      */
9321     boolean matchesProvider(Uri uri, ProviderInfo cpi) {
9322         String uriAuth = uri.getAuthority();
9323         String cpiAuth = cpi.authority;
9324         if (cpiAuth.indexOf(';') == -1) {
9325             return cpiAuth.equals(uriAuth);
9326         }
9327         String[] cpiAuths = cpiAuth.split(";");
9328         int length = cpiAuths.length;
9329         for (int i = 0; i < length; i++) {
9330             if (cpiAuths[i].equals(uriAuth)) return true;
9331         }
9332         return false;
9333     }
9334
9335     ContentProviderConnection incProviderCountLocked(ProcessRecord r,
9336             final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9337         if (r != null) {
9338             for (int i=0; i<r.conProviders.size(); i++) {
9339                 ContentProviderConnection conn = r.conProviders.get(i);
9340                 if (conn.provider == cpr) {
9341                     if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
9342                             "Adding provider requested by "
9343                             + r.processName + " from process "
9344                             + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9345                             + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9346                     if (stable) {
9347                         conn.stableCount++;
9348                         conn.numStableIncs++;
9349                     } else {
9350                         conn.unstableCount++;
9351                         conn.numUnstableIncs++;
9352                     }
9353                     return conn;
9354                 }
9355             }
9356             ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
9357             if (stable) {
9358                 conn.stableCount = 1;
9359                 conn.numStableIncs = 1;
9360             } else {
9361                 conn.unstableCount = 1;
9362                 conn.numUnstableIncs = 1;
9363             }
9364             cpr.connections.add(conn);
9365             r.conProviders.add(conn);
9366             startAssociationLocked(r.uid, r.processName, cpr.uid, cpr.name, cpr.info.processName);
9367             return conn;
9368         }
9369         cpr.addExternalProcessHandleLocked(externalProcessToken);
9370         return null;
9371     }
9372
9373     boolean decProviderCountLocked(ContentProviderConnection conn,
9374             ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9375         if (conn != null) {
9376             cpr = conn.provider;
9377             if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
9378                     "Removing provider requested by "
9379                     + conn.client.processName + " from process "
9380                     + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9381                     + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9382             if (stable) {
9383                 conn.stableCount--;
9384             } else {
9385                 conn.unstableCount--;
9386             }
9387             if (conn.stableCount == 0 && conn.unstableCount == 0) {
9388                 cpr.connections.remove(conn);
9389                 conn.client.conProviders.remove(conn);
9390                 stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
9391                 return true;
9392             }
9393             return false;
9394         }
9395         cpr.removeExternalProcessHandleLocked(externalProcessToken);
9396         return false;
9397     }
9398
9399     private void checkTime(long startTime, String where) {
9400         long now = SystemClock.elapsedRealtime();
9401         if ((now-startTime) > 1000) {
9402             // If we are taking more than a second, log about it.
9403             Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
9404         }
9405     }
9406
9407     private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
9408             String name, IBinder token, boolean stable, int userId) {
9409         ContentProviderRecord cpr;
9410         ContentProviderConnection conn = null;
9411         ProviderInfo cpi = null;
9412
9413         synchronized(this) {
9414             long startTime = SystemClock.elapsedRealtime();
9415
9416             ProcessRecord r = null;
9417             if (caller != null) {
9418                 r = getRecordForAppLocked(caller);
9419                 if (r == null) {
9420                     throw new SecurityException(
9421                             "Unable to find app for caller " + caller
9422                           + " (pid=" + Binder.getCallingPid()
9423                           + ") when getting content provider " + name);
9424                 }
9425             }
9426
9427             boolean checkCrossUser = true;
9428
9429             checkTime(startTime, "getContentProviderImpl: getProviderByName");
9430
9431             // First check if this content provider has been published...
9432             cpr = mProviderMap.getProviderByName(name, userId);
9433             // If that didn't work, check if it exists for user 0 and then
9434             // verify that it's a singleton provider before using it.
9435             if (cpr == null && userId != UserHandle.USER_OWNER) {
9436                 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
9437                 if (cpr != null) {
9438                     cpi = cpr.info;
9439                     if (isSingleton(cpi.processName, cpi.applicationInfo,
9440                             cpi.name, cpi.flags)
9441                             && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
9442                         userId = UserHandle.USER_OWNER;
9443                         checkCrossUser = false;
9444                     } else {
9445                         cpr = null;
9446                         cpi = null;
9447                     }
9448                 }
9449             }
9450
9451             boolean providerRunning = cpr != null;
9452             if (providerRunning) {
9453                 cpi = cpr.info;
9454                 String msg;
9455                 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9456                 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
9457                         != null) {
9458                     throw new SecurityException(msg);
9459                 }
9460                 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9461
9462                 if (r != null && cpr.canRunHere(r)) {
9463                     // This provider has been published or is in the process
9464                     // of being published...  but it is also allowed to run
9465                     // in the caller's process, so don't make a connection
9466                     // and just let the caller instantiate its own instance.
9467                     ContentProviderHolder holder = cpr.newHolder(null);
9468                     // don't give caller the provider object, it needs
9469                     // to make its own.
9470                     holder.provider = null;
9471                     return holder;
9472                 }
9473
9474                 final long origId = Binder.clearCallingIdentity();
9475
9476                 checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
9477
9478                 // In this case the provider instance already exists, so we can
9479                 // return it right away.
9480                 conn = incProviderCountLocked(r, cpr, token, stable);
9481                 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
9482                     if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
9483                         // If this is a perceptible app accessing the provider,
9484                         // make sure to count it as being accessed and thus
9485                         // back up on the LRU list.  This is good because
9486                         // content providers are often expensive to start.
9487                         checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
9488                         updateLruProcessLocked(cpr.proc, false, null);
9489                         checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
9490                     }
9491                 }
9492
9493                 if (cpr.proc != null) {
9494                     if (false) {
9495                         if (cpr.name.flattenToShortString().equals(
9496                                 "com.android.providers.calendar/.CalendarProvider2")) {
9497                             Slog.v(TAG, "****************** KILLING "
9498                                 + cpr.name.flattenToShortString());
9499                             Process.killProcess(cpr.proc.pid);
9500                         }
9501                     }
9502                     checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
9503                     boolean success = updateOomAdjLocked(cpr.proc);
9504                     maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
9505                     checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
9506                     if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
9507                     // NOTE: there is still a race here where a signal could be
9508                     // pending on the process even though we managed to update its
9509                     // adj level.  Not sure what to do about this, but at least
9510                     // the race is now smaller.
9511                     if (!success) {
9512                         // Uh oh...  it looks like the provider's process
9513                         // has been killed on us.  We need to wait for a new
9514                         // process to be started, and make sure its death
9515                         // doesn't kill our process.
9516                         Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
9517                                 + " is crashing; detaching " + r);
9518                         boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
9519                         checkTime(startTime, "getContentProviderImpl: before appDied");
9520                         appDiedLocked(cpr.proc);
9521                         checkTime(startTime, "getContentProviderImpl: after appDied");
9522                         if (!lastRef) {
9523                             // This wasn't the last ref our process had on
9524                             // the provider...  we have now been killed, bail.
9525                             return null;
9526                         }
9527                         providerRunning = false;
9528                         conn = null;
9529                     }
9530                 }
9531
9532                 Binder.restoreCallingIdentity(origId);
9533             }
9534
9535             boolean singleton;
9536             if (!providerRunning) {
9537                 try {
9538                     checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
9539                     cpi = AppGlobals.getPackageManager().
9540                         resolveContentProvider(name,
9541                             STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
9542                     checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
9543                 } catch (RemoteException ex) {
9544                 }
9545                 if (cpi == null) {
9546                     return null;
9547                 }
9548                 // If the provider is a singleton AND
9549                 // (it's a call within the same user || the provider is a
9550                 // privileged app)
9551                 // Then allow connecting to the singleton provider
9552                 singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9553                         cpi.name, cpi.flags)
9554                         && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
9555                 if (singleton) {
9556                     userId = UserHandle.USER_OWNER;
9557                 }
9558                 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
9559                 checkTime(startTime, "getContentProviderImpl: got app info for user");
9560
9561                 String msg;
9562                 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9563                 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
9564                         != null) {
9565                     throw new SecurityException(msg);
9566                 }
9567                 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9568
9569                 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
9570                         && !cpi.processName.equals("system")) {
9571                     // If this content provider does not run in the system
9572                     // process, and the system is not yet ready to run other
9573                     // processes, then fail fast instead of hanging.
9574                     throw new IllegalArgumentException(
9575                             "Attempt to launch content provider before system ready");
9576                 }
9577
9578                 // Make sure that the user who owns this provider is running.  If not,
9579                 // we don't want to allow it to run.
9580                 if (!isUserRunningLocked(userId, false)) {
9581                     Slog.w(TAG, "Unable to launch app "
9582                             + cpi.applicationInfo.packageName + "/"
9583                             + cpi.applicationInfo.uid + " for provider "
9584                             + name + ": user " + userId + " is stopped");
9585                     return null;
9586                 }
9587
9588                 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9589                 checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
9590                 cpr = mProviderMap.getProviderByClass(comp, userId);
9591                 checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
9592                 final boolean firstClass = cpr == null;
9593                 if (firstClass) {
9594                     final long ident = Binder.clearCallingIdentity();
9595                     try {
9596                         checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
9597                         ApplicationInfo ai =
9598                             AppGlobals.getPackageManager().
9599                                 getApplicationInfo(
9600                                         cpi.applicationInfo.packageName,
9601                                         STOCK_PM_FLAGS, userId);
9602                         checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
9603                         if (ai == null) {
9604                             Slog.w(TAG, "No package info for content provider "
9605                                     + cpi.name);
9606                             return null;
9607                         }
9608                         ai = getAppInfoForUser(ai, userId);
9609                         cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
9610                     } catch (RemoteException ex) {
9611                         // pm is in same process, this will never happen.
9612                     } finally {
9613                         Binder.restoreCallingIdentity(ident);
9614                     }
9615                 }
9616
9617                 checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
9618
9619                 if (r != null && cpr.canRunHere(r)) {
9620                     // If this is a multiprocess provider, then just return its
9621                     // info and allow the caller to instantiate it.  Only do
9622                     // this if the provider is the same user as the caller's
9623                     // process, or can run as root (so can be in any process).
9624                     return cpr.newHolder(null);
9625                 }
9626
9627                 if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
9628                             + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
9629                             + cpr.info.name + " callers=" + Debug.getCallers(6));
9630
9631                 // This is single process, and our app is now connecting to it.
9632                 // See if we are already in the process of launching this
9633                 // provider.
9634                 final int N = mLaunchingProviders.size();
9635                 int i;
9636                 for (i = 0; i < N; i++) {
9637                     if (mLaunchingProviders.get(i) == cpr) {
9638                         break;
9639                     }
9640                 }
9641
9642                 // If the provider is not already being launched, then get it
9643                 // started.
9644                 if (i >= N) {
9645                     final long origId = Binder.clearCallingIdentity();
9646
9647                     try {
9648                         // Content provider is now in use, its package can't be stopped.
9649                         try {
9650                             checkTime(startTime, "getContentProviderImpl: before set stopped state");
9651                             AppGlobals.getPackageManager().setPackageStoppedState(
9652                                     cpr.appInfo.packageName, false, userId);
9653                             checkTime(startTime, "getContentProviderImpl: after set stopped state");
9654                         } catch (RemoteException e) {
9655                         } catch (IllegalArgumentException e) {
9656                             Slog.w(TAG, "Failed trying to unstop package "
9657                                     + cpr.appInfo.packageName + ": " + e);
9658                         }
9659
9660                         // Use existing process if already started
9661                         checkTime(startTime, "getContentProviderImpl: looking for process record");
9662                         ProcessRecord proc = getProcessRecordLocked(
9663                                 cpi.processName, cpr.appInfo.uid, false);
9664                         if (proc != null && proc.thread != null) {
9665                             if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
9666                                     "Installing in existing process " + proc);
9667                             if (!proc.pubProviders.containsKey(cpi.name)) {
9668                                 checkTime(startTime, "getContentProviderImpl: scheduling install");
9669                                 proc.pubProviders.put(cpi.name, cpr);
9670                                 try {
9671                                     proc.thread.scheduleInstallProvider(cpi);
9672                                 } catch (RemoteException e) {
9673                                 }
9674                             }
9675                         } else {
9676                             checkTime(startTime, "getContentProviderImpl: before start process");
9677                             proc = startProcessLocked(cpi.processName,
9678                                     cpr.appInfo, false, 0, "content provider",
9679                                     new ComponentName(cpi.applicationInfo.packageName,
9680                                             cpi.name), false, false, false);
9681                             checkTime(startTime, "getContentProviderImpl: after start process");
9682                             if (proc == null) {
9683                                 Slog.w(TAG, "Unable to launch app "
9684                                         + cpi.applicationInfo.packageName + "/"
9685                                         + cpi.applicationInfo.uid + " for provider "
9686                                         + name + ": process is bad");
9687                                 return null;
9688                             }
9689                         }
9690                         cpr.launchingApp = proc;
9691                         mLaunchingProviders.add(cpr);
9692                     } finally {
9693                         Binder.restoreCallingIdentity(origId);
9694                     }
9695                 }
9696
9697                 checkTime(startTime, "getContentProviderImpl: updating data structures");
9698
9699                 // Make sure the provider is published (the same provider class
9700                 // may be published under multiple names).
9701                 if (firstClass) {
9702                     mProviderMap.putProviderByClass(comp, cpr);
9703                 }
9704
9705                 mProviderMap.putProviderByName(name, cpr);
9706                 conn = incProviderCountLocked(r, cpr, token, stable);
9707                 if (conn != null) {
9708                     conn.waiting = true;
9709                 }
9710             }
9711             checkTime(startTime, "getContentProviderImpl: done!");
9712         }
9713
9714         // Wait for the provider to be published...
9715         synchronized (cpr) {
9716             while (cpr.provider == null) {
9717                 if (cpr.launchingApp == null) {
9718                     Slog.w(TAG, "Unable to launch app "
9719                             + cpi.applicationInfo.packageName + "/"
9720                             + cpi.applicationInfo.uid + " for provider "
9721                             + name + ": launching app became null");
9722                     EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
9723                             UserHandle.getUserId(cpi.applicationInfo.uid),
9724                             cpi.applicationInfo.packageName,
9725                             cpi.applicationInfo.uid, name);
9726                     return null;
9727                 }
9728                 try {
9729                     if (DEBUG_MU) Slog.v(TAG_MU,
9730                             "Waiting to start provider " + cpr
9731                             + " launchingApp=" + cpr.launchingApp);
9732                     if (conn != null) {
9733                         conn.waiting = true;
9734                     }
9735                     cpr.wait();
9736                 } catch (InterruptedException ex) {
9737                 } finally {
9738                     if (conn != null) {
9739                         conn.waiting = false;
9740                     }
9741                 }
9742             }
9743         }
9744         return cpr != null ? cpr.newHolder(conn) : null;
9745     }
9746
9747     @Override
9748     public final ContentProviderHolder getContentProvider(
9749             IApplicationThread caller, String name, int userId, boolean stable) {
9750         enforceNotIsolatedCaller("getContentProvider");
9751         if (caller == null) {
9752             String msg = "null IApplicationThread when getting content provider "
9753                     + name;
9754             Slog.w(TAG, msg);
9755             throw new SecurityException(msg);
9756         }
9757         // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
9758         // with cross-user grant.
9759         return getContentProviderImpl(caller, name, null, stable, userId);
9760     }
9761
9762     public ContentProviderHolder getContentProviderExternal(
9763             String name, int userId, IBinder token) {
9764         enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9765             "Do not have permission in call getContentProviderExternal()");
9766         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
9767                 false, ALLOW_FULL_ONLY, "getContentProvider", null);
9768         return getContentProviderExternalUnchecked(name, token, userId);
9769     }
9770
9771     private ContentProviderHolder getContentProviderExternalUnchecked(String name,
9772             IBinder token, int userId) {
9773         return getContentProviderImpl(null, name, token, true, userId);
9774     }
9775
9776     /**
9777      * Drop a content provider from a ProcessRecord's bookkeeping
9778      */
9779     public void removeContentProvider(IBinder connection, boolean stable) {
9780         enforceNotIsolatedCaller("removeContentProvider");
9781         long ident = Binder.clearCallingIdentity();
9782         try {
9783             synchronized (this) {
9784                 ContentProviderConnection conn;
9785                 try {
9786                     conn = (ContentProviderConnection)connection;
9787                 } catch (ClassCastException e) {
9788                     String msg ="removeContentProvider: " + connection
9789                             + " not a ContentProviderConnection";
9790                     Slog.w(TAG, msg);
9791                     throw new IllegalArgumentException(msg);
9792                 }
9793                 if (conn == null) {
9794                     throw new NullPointerException("connection is null");
9795                 }
9796                 if (decProviderCountLocked(conn, null, null, stable)) {
9797                     updateOomAdjLocked();
9798                 }
9799             }
9800         } finally {
9801             Binder.restoreCallingIdentity(ident);
9802         }
9803     }
9804
9805     public void removeContentProviderExternal(String name, IBinder token) {
9806         enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9807             "Do not have permission in call removeContentProviderExternal()");
9808         int userId = UserHandle.getCallingUserId();
9809         long ident = Binder.clearCallingIdentity();
9810         try {
9811             removeContentProviderExternalUnchecked(name, token, userId);
9812         } finally {
9813             Binder.restoreCallingIdentity(ident);
9814         }
9815     }
9816
9817     private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
9818         synchronized (this) {
9819             ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
9820             if(cpr == null) {
9821                 //remove from mProvidersByClass
9822                 if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
9823                 return;
9824             }
9825
9826             //update content provider record entry info
9827             ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
9828             ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
9829             if (localCpr.hasExternalProcessHandles()) {
9830                 if (localCpr.removeExternalProcessHandleLocked(token)) {
9831                     updateOomAdjLocked();
9832                 } else {
9833                     Slog.e(TAG, "Attmpt to remove content provider " + localCpr
9834                             + " with no external reference for token: "
9835                             + token + ".");
9836                 }
9837             } else {
9838                 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
9839                         + " with no external references.");
9840             }
9841         }
9842     }
9843
9844     public final void publishContentProviders(IApplicationThread caller,
9845             List<ContentProviderHolder> providers) {
9846         if (providers == null) {
9847             return;
9848         }
9849
9850         enforceNotIsolatedCaller("publishContentProviders");
9851         synchronized (this) {
9852             final ProcessRecord r = getRecordForAppLocked(caller);
9853             if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
9854             if (r == null) {
9855                 throw new SecurityException(
9856                         "Unable to find app for caller " + caller
9857                       + " (pid=" + Binder.getCallingPid()
9858                       + ") when publishing content providers");
9859             }
9860
9861             final long origId = Binder.clearCallingIdentity();
9862
9863             final int N = providers.size();
9864             for (int i=0; i<N; i++) {
9865                 ContentProviderHolder src = providers.get(i);
9866                 if (src == null || src.info == null || src.provider == null) {
9867                     continue;
9868                 }
9869                 ContentProviderRecord dst = r.pubProviders.get(src.info.name);
9870                 if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
9871                 if (dst != null) {
9872                     ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
9873                     mProviderMap.putProviderByClass(comp, dst);
9874                     String names[] = dst.info.authority.split(";");
9875                     for (int j = 0; j < names.length; j++) {
9876                         mProviderMap.putProviderByName(names[j], dst);
9877                     }
9878
9879                     int NL = mLaunchingProviders.size();
9880                     int j;
9881                     for (j=0; j<NL; j++) {
9882                         if (mLaunchingProviders.get(j) == dst) {
9883                             mLaunchingProviders.remove(j);
9884                             j--;
9885                             NL--;
9886                         }
9887                     }
9888                     synchronized (dst) {
9889                         dst.provider = src.provider;
9890                         dst.proc = r;
9891                         dst.notifyAll();
9892                     }
9893                     updateOomAdjLocked(r);
9894                     maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
9895                             src.info.authority);
9896                 }
9897             }
9898
9899             Binder.restoreCallingIdentity(origId);
9900         }
9901     }
9902
9903     public boolean refContentProvider(IBinder connection, int stable, int unstable) {
9904         ContentProviderConnection conn;
9905         try {
9906             conn = (ContentProviderConnection)connection;
9907         } catch (ClassCastException e) {
9908             String msg ="refContentProvider: " + connection
9909                     + " not a ContentProviderConnection";
9910             Slog.w(TAG, msg);
9911             throw new IllegalArgumentException(msg);
9912         }
9913         if (conn == null) {
9914             throw new NullPointerException("connection is null");
9915         }
9916
9917         synchronized (this) {
9918             if (stable > 0) {
9919                 conn.numStableIncs += stable;
9920             }
9921             stable = conn.stableCount + stable;
9922             if (stable < 0) {
9923                 throw new IllegalStateException("stableCount < 0: " + stable);
9924             }
9925
9926             if (unstable > 0) {
9927                 conn.numUnstableIncs += unstable;
9928             }
9929             unstable = conn.unstableCount + unstable;
9930             if (unstable < 0) {
9931                 throw new IllegalStateException("unstableCount < 0: " + unstable);
9932             }
9933
9934             if ((stable+unstable) <= 0) {
9935                 throw new IllegalStateException("ref counts can't go to zero here: stable="
9936                         + stable + " unstable=" + unstable);
9937             }
9938             conn.stableCount = stable;
9939             conn.unstableCount = unstable;
9940             return !conn.dead;
9941         }
9942     }
9943
9944     public void unstableProviderDied(IBinder connection) {
9945         ContentProviderConnection conn;
9946         try {
9947             conn = (ContentProviderConnection)connection;
9948         } catch (ClassCastException e) {
9949             String msg ="refContentProvider: " + connection
9950                     + " not a ContentProviderConnection";
9951             Slog.w(TAG, msg);
9952             throw new IllegalArgumentException(msg);
9953         }
9954         if (conn == null) {
9955             throw new NullPointerException("connection is null");
9956         }
9957
9958         // Safely retrieve the content provider associated with the connection.
9959         IContentProvider provider;
9960         synchronized (this) {
9961             provider = conn.provider.provider;
9962         }
9963
9964         if (provider == null) {
9965             // Um, yeah, we're way ahead of you.
9966             return;
9967         }
9968
9969         // Make sure the caller is being honest with us.
9970         if (provider.asBinder().pingBinder()) {
9971             // Er, no, still looks good to us.
9972             synchronized (this) {
9973                 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
9974                         + " says " + conn + " died, but we don't agree");
9975                 return;
9976             }
9977         }
9978
9979         // Well look at that!  It's dead!
9980         synchronized (this) {
9981             if (conn.provider.provider != provider) {
9982                 // But something changed...  good enough.
9983                 return;
9984             }
9985
9986             ProcessRecord proc = conn.provider.proc;
9987             if (proc == null || proc.thread == null) {
9988                 // Seems like the process is already cleaned up.
9989                 return;
9990             }
9991
9992             // As far as we're concerned, this is just like receiving a
9993             // death notification...  just a bit prematurely.
9994             Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
9995                     + ") early provider death");
9996             final long ident = Binder.clearCallingIdentity();
9997             try {
9998                 appDiedLocked(proc);
9999             } finally {
10000                 Binder.restoreCallingIdentity(ident);
10001             }
10002         }
10003     }
10004
10005     @Override
10006     public void appNotRespondingViaProvider(IBinder connection) {
10007         enforceCallingPermission(
10008                 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
10009
10010         final ContentProviderConnection conn = (ContentProviderConnection) connection;
10011         if (conn == null) {
10012             Slog.w(TAG, "ContentProviderConnection is null");
10013             return;
10014         }
10015
10016         final ProcessRecord host = conn.provider.proc;
10017         if (host == null) {
10018             Slog.w(TAG, "Failed to find hosting ProcessRecord");
10019             return;
10020         }
10021
10022         final long token = Binder.clearCallingIdentity();
10023         try {
10024             appNotResponding(host, null, null, false, "ContentProvider not responding");
10025         } finally {
10026             Binder.restoreCallingIdentity(token);
10027         }
10028     }
10029
10030     public final void installSystemProviders() {
10031         List<ProviderInfo> providers;
10032         synchronized (this) {
10033             ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
10034             providers = generateApplicationProvidersLocked(app);
10035             if (providers != null) {
10036                 for (int i=providers.size()-1; i>=0; i--) {
10037                     ProviderInfo pi = (ProviderInfo)providers.get(i);
10038                     if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
10039                         Slog.w(TAG, "Not installing system proc provider " + pi.name
10040                                 + ": not system .apk");
10041                         providers.remove(i);
10042                     }
10043                 }
10044             }
10045         }
10046         if (providers != null) {
10047             mSystemThread.installSystemProviders(providers);
10048         }
10049
10050         mCoreSettingsObserver = new CoreSettingsObserver(this);
10051
10052         //mUsageStatsService.monitorPackages();
10053     }
10054
10055     /**
10056      * Allows apps to retrieve the MIME type of a URI.
10057      * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
10058      * users, then it does not need permission to access the ContentProvider.
10059      * Either, it needs cross-user uri grants.
10060      *
10061      * CTS tests for this functionality can be run with "runtest cts-appsecurity".
10062      *
10063      * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
10064      *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
10065      */
10066     public String getProviderMimeType(Uri uri, int userId) {
10067         enforceNotIsolatedCaller("getProviderMimeType");
10068         final String name = uri.getAuthority();
10069         int callingUid = Binder.getCallingUid();
10070         int callingPid = Binder.getCallingPid();
10071         long ident = 0;
10072         boolean clearedIdentity = false;
10073         userId = unsafeConvertIncomingUser(userId);
10074         if (canClearIdentity(callingPid, callingUid, userId)) {
10075             clearedIdentity = true;
10076             ident = Binder.clearCallingIdentity();
10077         }
10078         ContentProviderHolder holder = null;
10079         try {
10080             holder = getContentProviderExternalUnchecked(name, null, userId);
10081             if (holder != null) {
10082                 return holder.provider.getType(uri);
10083             }
10084         } catch (RemoteException e) {
10085             Log.w(TAG, "Content provider dead retrieving " + uri, e);
10086             return null;
10087         } finally {
10088             // We need to clear the identity to call removeContentProviderExternalUnchecked
10089             if (!clearedIdentity) {
10090                 ident = Binder.clearCallingIdentity();
10091             }
10092             try {
10093                 if (holder != null) {
10094                     removeContentProviderExternalUnchecked(name, null, userId);
10095                 }
10096             } finally {
10097                 Binder.restoreCallingIdentity(ident);
10098             }
10099         }
10100
10101         return null;
10102     }
10103
10104     private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
10105         if (UserHandle.getUserId(callingUid) == userId) {
10106             return true;
10107         }
10108         if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
10109                 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
10110                 || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
10111                 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
10112                 return true;
10113         }
10114         return false;
10115     }
10116
10117     // =========================================================
10118     // GLOBAL MANAGEMENT
10119     // =========================================================
10120
10121     final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
10122             boolean isolated, int isolatedUid) {
10123         String proc = customProcess != null ? customProcess : info.processName;
10124         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10125         final int userId = UserHandle.getUserId(info.uid);
10126         int uid = info.uid;
10127         if (isolated) {
10128             if (isolatedUid == 0) {
10129                 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
10130                 while (true) {
10131                     if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
10132                             || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
10133                         mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
10134                     }
10135                     uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
10136                     mNextIsolatedProcessUid++;
10137                     if (mIsolatedProcesses.indexOfKey(uid) < 0) {
10138                         // No process for this uid, use it.
10139                         break;
10140                     }
10141                     stepsLeft--;
10142                     if (stepsLeft <= 0) {
10143                         return null;
10144                     }
10145                 }
10146             } else {
10147                 // Special case for startIsolatedProcess (internal only), where
10148                 // the uid of the isolated process is specified by the caller.
10149                 uid = isolatedUid;
10150             }
10151         }
10152         final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
10153         if (!mBooted && !mBooting
10154                 && userId == UserHandle.USER_OWNER
10155                 && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
10156             r.persistent = true;
10157         }
10158         addProcessNameLocked(r);
10159         return r;
10160     }
10161
10162     final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
10163             String abiOverride) {
10164         ProcessRecord app;
10165         if (!isolated) {
10166             app = getProcessRecordLocked(info.processName, info.uid, true);
10167         } else {
10168             app = null;
10169         }
10170
10171         if (app == null) {
10172             app = newProcessRecordLocked(info, null, isolated, 0);
10173             updateLruProcessLocked(app, false, null);
10174             updateOomAdjLocked();
10175         }
10176
10177         // This package really, really can not be stopped.
10178         try {
10179             AppGlobals.getPackageManager().setPackageStoppedState(
10180                     info.packageName, false, UserHandle.getUserId(app.uid));
10181         } catch (RemoteException e) {
10182         } catch (IllegalArgumentException e) {
10183             Slog.w(TAG, "Failed trying to unstop package "
10184                     + info.packageName + ": " + e);
10185         }
10186
10187         if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
10188             app.persistent = true;
10189             app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
10190         }
10191         if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
10192             mPersistentStartingProcesses.add(app);
10193             startProcessLocked(app, "added application", app.processName, abiOverride,
10194                     null /* entryPoint */, null /* entryPointArgs */);
10195         }
10196
10197         return app;
10198     }
10199
10200     public void unhandledBack() {
10201         enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
10202                 "unhandledBack()");
10203
10204         synchronized(this) {
10205             final long origId = Binder.clearCallingIdentity();
10206             try {
10207                 getFocusedStack().unhandledBackLocked();
10208             } finally {
10209                 Binder.restoreCallingIdentity(origId);
10210             }
10211         }
10212     }
10213
10214     public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
10215         enforceNotIsolatedCaller("openContentUri");
10216         final int userId = UserHandle.getCallingUserId();
10217         String name = uri.getAuthority();
10218         ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
10219         ParcelFileDescriptor pfd = null;
10220         if (cph != null) {
10221             // We record the binder invoker's uid in thread-local storage before
10222             // going to the content provider to open the file.  Later, in the code
10223             // that handles all permissions checks, we look for this uid and use
10224             // that rather than the Activity Manager's own uid.  The effect is that
10225             // we do the check against the caller's permissions even though it looks
10226             // to the content provider like the Activity Manager itself is making
10227             // the request.
10228             Binder token = new Binder();
10229             sCallerIdentity.set(new Identity(
10230                     token, Binder.getCallingPid(), Binder.getCallingUid()));
10231             try {
10232                 pfd = cph.provider.openFile(null, uri, "r", null, token);
10233             } catch (FileNotFoundException e) {
10234                 // do nothing; pfd will be returned null
10235             } finally {
10236                 // Ensure that whatever happens, we clean up the identity state
10237                 sCallerIdentity.remove();
10238                 // Ensure we're done with the provider.
10239                 removeContentProviderExternalUnchecked(name, null, userId);
10240             }
10241         } else {
10242             Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
10243         }
10244         return pfd;
10245     }
10246
10247     // Actually is sleeping or shutting down or whatever else in the future
10248     // is an inactive state.
10249     public boolean isSleepingOrShuttingDown() {
10250         return isSleeping() || mShuttingDown;
10251     }
10252
10253     public boolean isSleeping() {
10254         return mSleeping;
10255     }
10256
10257     void onWakefulnessChanged(int wakefulness) {
10258         synchronized(this) {
10259             mWakefulness = wakefulness;
10260             updateSleepIfNeededLocked();
10261         }
10262     }
10263
10264     void finishRunningVoiceLocked() {
10265         if (mRunningVoice != null) {
10266             mRunningVoice = null;
10267             mVoiceWakeLock.release();
10268             updateSleepIfNeededLocked();
10269         }
10270     }
10271
10272     void startTimeTrackingFocusedActivityLocked() {
10273         if (!mSleeping && mCurAppTimeTracker != null && mFocusedActivity != null) {
10274             mCurAppTimeTracker.start(mFocusedActivity.packageName);
10275         }
10276     }
10277
10278     void updateSleepIfNeededLocked() {
10279         if (mSleeping && !shouldSleepLocked()) {
10280             mSleeping = false;
10281             startTimeTrackingFocusedActivityLocked();
10282             mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
10283             mStackSupervisor.comeOutOfSleepIfNeededLocked();
10284             updateOomAdjLocked();
10285         } else if (!mSleeping && shouldSleepLocked()) {
10286             mSleeping = true;
10287             if (mCurAppTimeTracker != null) {
10288                 mCurAppTimeTracker.stop();
10289             }
10290             mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
10291             mStackSupervisor.goingToSleepLocked();
10292             updateOomAdjLocked();
10293
10294             // Initialize the wake times of all processes.
10295             checkExcessivePowerUsageLocked(false);
10296             mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
10297             Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
10298             mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
10299         }
10300     }
10301
10302     private boolean shouldSleepLocked() {
10303         // Resume applications while running a voice interactor.
10304         if (mRunningVoice != null) {
10305             return false;
10306         }
10307
10308         // TODO: Transform the lock screen state into a sleep token instead.
10309         switch (mWakefulness) {
10310             case PowerManagerInternal.WAKEFULNESS_AWAKE:
10311             case PowerManagerInternal.WAKEFULNESS_DREAMING:
10312             case PowerManagerInternal.WAKEFULNESS_DOZING:
10313                 // Pause applications whenever the lock screen is shown or any sleep
10314                 // tokens have been acquired.
10315                 return (mLockScreenShown != LOCK_SCREEN_HIDDEN || !mSleepTokens.isEmpty());
10316             case PowerManagerInternal.WAKEFULNESS_ASLEEP:
10317             default:
10318                 // If we're asleep then pause applications unconditionally.
10319                 return true;
10320         }
10321     }
10322
10323     /** Pokes the task persister. */
10324     void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
10325         if (task != null && task.stack != null && task.stack.isHomeStack()) {
10326             // Never persist the home stack.
10327             return;
10328         }
10329         mTaskPersister.wakeup(task, flush);
10330     }
10331
10332     /** Notifies all listeners when the task stack has changed. */
10333     void notifyTaskStackChangedLocked() {
10334         mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
10335         Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
10336         mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
10337     }
10338
10339     @Override
10340     public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
10341         mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
10342     }
10343
10344     @Override
10345     public boolean shutdown(int timeout) {
10346         if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
10347                 != PackageManager.PERMISSION_GRANTED) {
10348             throw new SecurityException("Requires permission "
10349                     + android.Manifest.permission.SHUTDOWN);
10350         }
10351
10352         boolean timedout = false;
10353
10354         synchronized(this) {
10355             mShuttingDown = true;
10356             updateEventDispatchingLocked();
10357             timedout = mStackSupervisor.shutdownLocked(timeout);
10358         }
10359
10360         mAppOpsService.shutdown();
10361         if (mUsageStatsService != null) {
10362             mUsageStatsService.prepareShutdown();
10363         }
10364         mBatteryStatsService.shutdown();
10365         synchronized (this) {
10366             mProcessStats.shutdownLocked();
10367             notifyTaskPersisterLocked(null, true);
10368         }
10369
10370         return timedout;
10371     }
10372
10373     public final void activitySlept(IBinder token) {
10374         if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
10375
10376         final long origId = Binder.clearCallingIdentity();
10377
10378         synchronized (this) {
10379             final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10380             if (r != null) {
10381                 mStackSupervisor.activitySleptLocked(r);
10382             }
10383         }
10384
10385         Binder.restoreCallingIdentity(origId);
10386     }
10387
10388     private String lockScreenShownToString() {
10389         switch (mLockScreenShown) {
10390             case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
10391             case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
10392             case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
10393             default: return "Unknown=" + mLockScreenShown;
10394         }
10395     }
10396
10397     void logLockScreen(String msg) {
10398         if (DEBUG_LOCKSCREEN) Slog.d(TAG_LOCKSCREEN, Debug.getCallers(2) + ":" + msg
10399                 + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
10400                 + PowerManagerInternal.wakefulnessToString(mWakefulness)
10401                 + " mSleeping=" + mSleeping);
10402     }
10403
10404     void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
10405         mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
10406         if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
10407             boolean wasRunningVoice = mRunningVoice != null;
10408             mRunningVoice = session;
10409             if (!wasRunningVoice) {
10410                 mVoiceWakeLock.acquire();
10411                 updateSleepIfNeededLocked();
10412             }
10413         }
10414     }
10415
10416     private void updateEventDispatchingLocked() {
10417         mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
10418     }
10419
10420     public void setLockScreenShown(boolean shown) {
10421         if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
10422                 != PackageManager.PERMISSION_GRANTED) {
10423             throw new SecurityException("Requires permission "
10424                     + android.Manifest.permission.DEVICE_POWER);
10425         }
10426
10427         synchronized(this) {
10428             long ident = Binder.clearCallingIdentity();
10429             try {
10430                 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
10431                 mLockScreenShown = shown ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
10432                 updateSleepIfNeededLocked();
10433             } finally {
10434                 Binder.restoreCallingIdentity(ident);
10435             }
10436         }
10437     }
10438
10439     @Override
10440     public void stopAppSwitches() {
10441         if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10442                 != PackageManager.PERMISSION_GRANTED) {
10443             throw new SecurityException("Requires permission "
10444                     + android.Manifest.permission.STOP_APP_SWITCHES);
10445         }
10446
10447         synchronized(this) {
10448             mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
10449                     + APP_SWITCH_DELAY_TIME;
10450             mDidAppSwitch = false;
10451             mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10452             Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10453             mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
10454         }
10455     }
10456
10457     public void resumeAppSwitches() {
10458         if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10459                 != PackageManager.PERMISSION_GRANTED) {
10460             throw new SecurityException("Requires permission "
10461                     + android.Manifest.permission.STOP_APP_SWITCHES);
10462         }
10463
10464         synchronized(this) {
10465             // Note that we don't execute any pending app switches... we will
10466             // let those wait until either the timeout, or the next start
10467             // activity request.
10468             mAppSwitchesAllowedTime = 0;
10469         }
10470     }
10471
10472     boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
10473             int callingPid, int callingUid, String name) {
10474         if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
10475             return true;
10476         }
10477
10478         int perm = checkComponentPermission(
10479                 android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
10480                 sourceUid, -1, true);
10481         if (perm == PackageManager.PERMISSION_GRANTED) {
10482             return true;
10483         }
10484
10485         // If the actual IPC caller is different from the logical source, then
10486         // also see if they are allowed to control app switches.
10487         if (callingUid != -1 && callingUid != sourceUid) {
10488             perm = checkComponentPermission(
10489                     android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
10490                     callingUid, -1, true);
10491             if (perm == PackageManager.PERMISSION_GRANTED) {
10492                 return true;
10493             }
10494         }
10495
10496         Slog.w(TAG, name + " request from " + sourceUid + " stopped");
10497         return false;
10498     }
10499
10500     public void setDebugApp(String packageName, boolean waitForDebugger,
10501             boolean persistent) {
10502         enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
10503                 "setDebugApp()");
10504
10505         long ident = Binder.clearCallingIdentity();
10506         try {
10507             // Note that this is not really thread safe if there are multiple
10508             // callers into it at the same time, but that's not a situation we
10509             // care about.
10510             if (persistent) {
10511                 final ContentResolver resolver = mContext.getContentResolver();
10512                 Settings.Global.putString(
10513                     resolver, Settings.Global.DEBUG_APP,
10514                     packageName);
10515                 Settings.Global.putInt(
10516                     resolver, Settings.Global.WAIT_FOR_DEBUGGER,
10517                     waitForDebugger ? 1 : 0);
10518             }
10519
10520             synchronized (this) {
10521                 if (!persistent) {
10522                     mOrigDebugApp = mDebugApp;
10523                     mOrigWaitForDebugger = mWaitForDebugger;
10524                 }
10525                 mDebugApp = packageName;
10526                 mWaitForDebugger = waitForDebugger;
10527                 mDebugTransient = !persistent;
10528                 if (packageName != null) {
10529                     forceStopPackageLocked(packageName, -1, false, false, true, true,
10530                             false, UserHandle.USER_ALL, "set debug app");
10531                 }
10532             }
10533         } finally {
10534             Binder.restoreCallingIdentity(ident);
10535         }
10536     }
10537
10538     void setOpenGlTraceApp(ApplicationInfo app, String processName) {
10539         synchronized (this) {
10540             boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10541             if (!isDebuggable) {
10542                 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10543                     throw new SecurityException("Process not debuggable: " + app.packageName);
10544                 }
10545             }
10546
10547             mOpenGlTraceApp = processName;
10548         }
10549     }
10550
10551     void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
10552         synchronized (this) {
10553             boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10554             if (!isDebuggable) {
10555                 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10556                     throw new SecurityException("Process not debuggable: " + app.packageName);
10557                 }
10558             }
10559             mProfileApp = processName;
10560             mProfileFile = profilerInfo.profileFile;
10561             if (mProfileFd != null) {
10562                 try {
10563                     mProfileFd.close();
10564                 } catch (IOException e) {
10565                 }
10566                 mProfileFd = null;
10567             }
10568             mProfileFd = profilerInfo.profileFd;
10569             mSamplingInterval = profilerInfo.samplingInterval;
10570             mAutoStopProfiler = profilerInfo.autoStopProfiler;
10571             mProfileType = 0;
10572         }
10573     }
10574
10575     @Override
10576     public void setAlwaysFinish(boolean enabled) {
10577         enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
10578                 "setAlwaysFinish()");
10579
10580         Settings.Global.putInt(
10581                 mContext.getContentResolver(),
10582                 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
10583
10584         synchronized (this) {
10585             mAlwaysFinishActivities = enabled;
10586         }
10587     }
10588
10589     @Override
10590     public void setActivityController(IActivityController controller) {
10591         enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10592                 "setActivityController()");
10593         synchronized (this) {
10594             mController = controller;
10595             Watchdog.getInstance().setActivityController(controller);
10596         }
10597     }
10598
10599     @Override
10600     public void setUserIsMonkey(boolean userIsMonkey) {
10601         synchronized (this) {
10602             synchronized (mPidsSelfLocked) {
10603                 final int callingPid = Binder.getCallingPid();
10604                 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
10605                 if (precessRecord == null) {
10606                     throw new SecurityException("Unknown process: " + callingPid);
10607                 }
10608                 if (precessRecord.instrumentationUiAutomationConnection  == null) {
10609                     throw new SecurityException("Only an instrumentation process "
10610                             + "with a UiAutomation can call setUserIsMonkey");
10611                 }
10612             }
10613             mUserIsMonkey = userIsMonkey;
10614         }
10615     }
10616
10617     @Override
10618     public boolean isUserAMonkey() {
10619         synchronized (this) {
10620             // If there is a controller also implies the user is a monkey.
10621             return (mUserIsMonkey || mController != null);
10622         }
10623     }
10624
10625     public void requestBugReport() {
10626         enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
10627         SystemProperties.set("ctl.start", "bugreport");
10628     }
10629
10630     public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
10631         return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
10632     }
10633
10634     public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
10635         if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
10636             return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
10637         }
10638         return KEY_DISPATCHING_TIMEOUT;
10639     }
10640
10641     @Override
10642     public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
10643         if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10644                 != PackageManager.PERMISSION_GRANTED) {
10645             throw new SecurityException("Requires permission "
10646                     + android.Manifest.permission.FILTER_EVENTS);
10647         }
10648         ProcessRecord proc;
10649         long timeout;
10650         synchronized (this) {
10651             synchronized (mPidsSelfLocked) {
10652                 proc = mPidsSelfLocked.get(pid);
10653             }
10654             timeout = getInputDispatchingTimeoutLocked(proc);
10655         }
10656
10657         if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
10658             return -1;
10659         }
10660
10661         return timeout;
10662     }
10663
10664     /**
10665      * Handle input dispatching timeouts.
10666      * Returns whether input dispatching should be aborted or not.
10667      */
10668     public boolean inputDispatchingTimedOut(final ProcessRecord proc,
10669             final ActivityRecord activity, final ActivityRecord parent,
10670             final boolean aboveSystem, String reason) {
10671         if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10672                 != PackageManager.PERMISSION_GRANTED) {
10673             throw new SecurityException("Requires permission "
10674                     + android.Manifest.permission.FILTER_EVENTS);
10675         }
10676
10677         final String annotation;
10678         if (reason == null) {
10679             annotation = "Input dispatching timed out";
10680         } else {
10681             annotation = "Input dispatching timed out (" + reason + ")";
10682         }
10683
10684         if (proc != null) {
10685             synchronized (this) {
10686                 if (proc.debugging) {
10687                     return false;
10688                 }
10689
10690                 if (mDidDexOpt) {
10691                     // Give more time since we were dexopting.
10692                     mDidDexOpt = false;
10693                     return false;
10694                 }
10695
10696                 if (proc.instrumentationClass != null) {
10697                     Bundle info = new Bundle();
10698                     info.putString("shortMsg", "keyDispatchingTimedOut");
10699                     info.putString("longMsg", annotation);
10700                     finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
10701                     return true;
10702                 }
10703             }
10704             mHandler.post(new Runnable() {
10705                 @Override
10706                 public void run() {
10707                     appNotResponding(proc, activity, parent, aboveSystem, annotation);
10708                 }
10709             });
10710         }
10711
10712         return true;
10713     }
10714
10715     @Override
10716     public Bundle getAssistContextExtras(int requestType) {
10717         PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
10718                 null, UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT);
10719         if (pae == null) {
10720             return null;
10721         }
10722         synchronized (pae) {
10723             while (!pae.haveResult) {
10724                 try {
10725                     pae.wait();
10726                 } catch (InterruptedException e) {
10727                 }
10728             }
10729         }
10730         synchronized (this) {
10731             buildAssistBundleLocked(pae, pae.result);
10732             mPendingAssistExtras.remove(pae);
10733             mUiHandler.removeCallbacks(pae);
10734         }
10735         return pae.extras;
10736     }
10737
10738     @Override
10739     public boolean isAssistDataAllowedOnCurrentActivity() {
10740         int userId = mCurrentUserId;
10741         synchronized (this) {
10742             ActivityRecord activity = getFocusedStack().topActivity();
10743             if (activity == null) {
10744                 return false;
10745             }
10746             userId = activity.userId;
10747         }
10748         DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
10749                 Context.DEVICE_POLICY_SERVICE);
10750         return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
10751     }
10752
10753     @Override
10754     public boolean showAssistFromActivity(IBinder token, Bundle args) {
10755         long ident = Binder.clearCallingIdentity();
10756         try {
10757             synchronized (this) {
10758                 ActivityRecord caller = ActivityRecord.forTokenLocked(token);
10759                 ActivityRecord top = getFocusedStack().topActivity();
10760                 if (top != caller) {
10761                     Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
10762                             + " is not current top " + top);
10763                     return false;
10764                 }
10765                 if (!top.nowVisible) {
10766                     Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
10767                             + " is not visible");
10768                     return false;
10769                 }
10770             }
10771             AssistUtils utils = new AssistUtils(mContext);
10772             return utils.showSessionForActiveService(args,
10773                     VoiceInteractionSession.SHOW_SOURCE_APPLICATION, null, token);
10774         } finally {
10775             Binder.restoreCallingIdentity(ident);
10776         }
10777     }
10778
10779     @Override
10780     public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
10781             IBinder activityToken) {
10782         return enqueueAssistContext(requestType, null, null, receiver, activityToken,
10783                 UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_LONG_TIMEOUT) != null;
10784     }
10785
10786     private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
10787             IResultReceiver receiver, IBinder activityToken, int userHandle, Bundle args,
10788             long timeout) {
10789         enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
10790                 "enqueueAssistContext()");
10791         synchronized (this) {
10792             ActivityRecord activity = getFocusedStack().topActivity();
10793             if (activity == null) {
10794                 Slog.w(TAG, "getAssistContextExtras failed: no top activity");
10795                 return null;
10796             }
10797             if (activity.app == null || activity.app.thread == null) {
10798                 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
10799                 return null;
10800             }
10801             if (activityToken != null) {
10802                 ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
10803                 if (activity != caller) {
10804                     Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
10805                             + " is not current top " + activity);
10806                     return null;
10807                 }
10808             }
10809             PendingAssistExtras pae;
10810             Bundle extras = new Bundle();
10811             if (args != null) {
10812                 extras.putAll(args);
10813             }
10814             extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
10815             extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
10816             pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, userHandle);
10817             try {
10818                 activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
10819                         requestType);
10820                 mPendingAssistExtras.add(pae);
10821                 mUiHandler.postDelayed(pae, timeout);
10822             } catch (RemoteException e) {
10823                 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
10824                 return null;
10825             }
10826             return pae;
10827         }
10828     }
10829
10830     void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
10831         IResultReceiver receiver;
10832         synchronized (this) {
10833             mPendingAssistExtras.remove(pae);
10834             receiver = pae.receiver;
10835         }
10836         if (receiver != null) {
10837             // Caller wants result sent back to them.
10838             try {
10839                 pae.receiver.send(0, null);
10840             } catch (RemoteException e) {
10841             }
10842         }
10843     }
10844
10845     private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
10846         if (result != null) {
10847             pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
10848         }
10849         if (pae.hint != null) {
10850             pae.extras.putBoolean(pae.hint, true);
10851         }
10852     }
10853
10854     public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
10855             AssistContent content, Uri referrer) {
10856         PendingAssistExtras pae = (PendingAssistExtras)token;
10857         synchronized (pae) {
10858             pae.result = extras;
10859             pae.structure = structure;
10860             pae.content = content;
10861             if (referrer != null) {
10862                 pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
10863             }
10864             pae.haveResult = true;
10865             pae.notifyAll();
10866             if (pae.intent == null && pae.receiver == null) {
10867                 // Caller is just waiting for the result.
10868                 return;
10869             }
10870         }
10871
10872         // We are now ready to launch the assist activity.
10873         IResultReceiver sendReceiver = null;
10874         Bundle sendBundle = null;
10875         synchronized (this) {
10876             buildAssistBundleLocked(pae, extras);
10877             boolean exists = mPendingAssistExtras.remove(pae);
10878             mUiHandler.removeCallbacks(pae);
10879             if (!exists) {
10880                 // Timed out.
10881                 return;
10882             }
10883             if ((sendReceiver=pae.receiver) != null) {
10884                 // Caller wants result sent back to them.
10885                 sendBundle = new Bundle();
10886                 sendBundle.putBundle("data", pae.extras);
10887                 sendBundle.putParcelable("structure", pae.structure);
10888                 sendBundle.putParcelable("content", pae.content);
10889             }
10890         }
10891         if (sendReceiver != null) {
10892             try {
10893                 sendReceiver.send(0, sendBundle);
10894             } catch (RemoteException e) {
10895             }
10896             return;
10897         }
10898
10899         long ident = Binder.clearCallingIdentity();
10900         try {
10901             pae.intent.replaceExtras(pae.extras);
10902             pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10903                     | Intent.FLAG_ACTIVITY_SINGLE_TOP
10904                     | Intent.FLAG_ACTIVITY_CLEAR_TOP);
10905             closeSystemDialogs("assist");
10906             try {
10907                 mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
10908             } catch (ActivityNotFoundException e) {
10909                 Slog.w(TAG, "No activity to handle assist action.", e);
10910             }
10911         } finally {
10912             Binder.restoreCallingIdentity(ident);
10913         }
10914     }
10915
10916     public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
10917             Bundle args) {
10918         return enqueueAssistContext(requestType, intent, hint, null, null, userHandle, args,
10919                 PENDING_ASSIST_EXTRAS_TIMEOUT) != null;
10920     }
10921
10922     public void registerProcessObserver(IProcessObserver observer) {
10923         enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10924                 "registerProcessObserver()");
10925         synchronized (this) {
10926             mProcessObservers.register(observer);
10927         }
10928     }
10929
10930     @Override
10931     public void unregisterProcessObserver(IProcessObserver observer) {
10932         synchronized (this) {
10933             mProcessObservers.unregister(observer);
10934         }
10935     }
10936
10937     public void registerUidObserver(IUidObserver observer) {
10938         enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10939                 "registerUidObserver()");
10940         synchronized (this) {
10941             mUidObservers.register(observer);
10942         }
10943     }
10944
10945     @Override
10946     public void unregisterUidObserver(IUidObserver observer) {
10947         synchronized (this) {
10948             mUidObservers.unregister(observer);
10949         }
10950     }
10951
10952     @Override
10953     public boolean convertFromTranslucent(IBinder token) {
10954         final long origId = Binder.clearCallingIdentity();
10955         try {
10956             synchronized (this) {
10957                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10958                 if (r == null) {
10959                     return false;
10960                 }
10961                 final boolean translucentChanged = r.changeWindowTranslucency(true);
10962                 if (translucentChanged) {
10963                     r.task.stack.releaseBackgroundResources(r);
10964                     mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10965                 }
10966                 mWindowManager.setAppFullscreen(token, true);
10967                 return translucentChanged;
10968             }
10969         } finally {
10970             Binder.restoreCallingIdentity(origId);
10971         }
10972     }
10973
10974     @Override
10975     public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
10976         final long origId = Binder.clearCallingIdentity();
10977         try {
10978             synchronized (this) {
10979                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10980                 if (r == null) {
10981                     return false;
10982                 }
10983                 int index = r.task.mActivities.lastIndexOf(r);
10984                 if (index > 0) {
10985                     ActivityRecord under = r.task.mActivities.get(index - 1);
10986                     under.returningOptions = options;
10987                 }
10988                 final boolean translucentChanged = r.changeWindowTranslucency(false);
10989                 if (translucentChanged) {
10990                     r.task.stack.convertActivityToTranslucent(r);
10991                 }
10992                 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10993                 mWindowManager.setAppFullscreen(token, false);
10994                 return translucentChanged;
10995             }
10996         } finally {
10997             Binder.restoreCallingIdentity(origId);
10998         }
10999     }
11000
11001     @Override
11002     public boolean requestVisibleBehind(IBinder token, boolean visible) {
11003         final long origId = Binder.clearCallingIdentity();
11004         try {
11005             synchronized (this) {
11006                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11007                 if (r != null) {
11008                     return mStackSupervisor.requestVisibleBehindLocked(r, visible);
11009                 }
11010             }
11011             return false;
11012         } finally {
11013             Binder.restoreCallingIdentity(origId);
11014         }
11015     }
11016
11017     @Override
11018     public boolean isBackgroundVisibleBehind(IBinder token) {
11019         final long origId = Binder.clearCallingIdentity();
11020         try {
11021             synchronized (this) {
11022                 final ActivityStack stack = ActivityRecord.getStackLocked(token);
11023                 final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
11024                 if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
11025                         "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
11026                 return visible;
11027             }
11028         } finally {
11029             Binder.restoreCallingIdentity(origId);
11030         }
11031     }
11032
11033     @Override
11034     public ActivityOptions getActivityOptions(IBinder token) {
11035         final long origId = Binder.clearCallingIdentity();
11036         try {
11037             synchronized (this) {
11038                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11039                 if (r != null) {
11040                     final ActivityOptions activityOptions = r.pendingOptions;
11041                     r.pendingOptions = null;
11042                     return activityOptions;
11043                 }
11044                 return null;
11045             }
11046         } finally {
11047             Binder.restoreCallingIdentity(origId);
11048         }
11049     }
11050
11051     @Override
11052     public void setImmersive(IBinder token, boolean immersive) {
11053         synchronized(this) {
11054             final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11055             if (r == null) {
11056                 throw new IllegalArgumentException();
11057             }
11058             r.immersive = immersive;
11059
11060             // update associated state if we're frontmost
11061             if (r == mFocusedActivity) {
11062                 if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
11063                 applyUpdateLockStateLocked(r);
11064             }
11065         }
11066     }
11067
11068     @Override
11069     public boolean isImmersive(IBinder token) {
11070         synchronized (this) {
11071             ActivityRecord r = ActivityRecord.isInStackLocked(token);
11072             if (r == null) {
11073                 throw new IllegalArgumentException();
11074             }
11075             return r.immersive;
11076         }
11077     }
11078
11079     public boolean isTopActivityImmersive() {
11080         enforceNotIsolatedCaller("startActivity");
11081         synchronized (this) {
11082             ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
11083             return (r != null) ? r.immersive : false;
11084         }
11085     }
11086
11087     @Override
11088     public boolean isTopOfTask(IBinder token) {
11089         synchronized (this) {
11090             ActivityRecord r = ActivityRecord.isInStackLocked(token);
11091             if (r == null) {
11092                 throw new IllegalArgumentException();
11093             }
11094             return r.task.getTopActivity() == r;
11095         }
11096     }
11097
11098     public final void enterSafeMode() {
11099         synchronized(this) {
11100             // It only makes sense to do this before the system is ready
11101             // and started launching other packages.
11102             if (!mSystemReady) {
11103                 try {
11104                     AppGlobals.getPackageManager().enterSafeMode();
11105                 } catch (RemoteException e) {
11106                 }
11107             }
11108
11109             mSafeMode = true;
11110         }
11111     }
11112
11113     public final void showSafeModeOverlay() {
11114         View v = LayoutInflater.from(mContext).inflate(
11115                 com.android.internal.R.layout.safe_mode, null);
11116         WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
11117         lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
11118         lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
11119         lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
11120         lp.gravity = Gravity.BOTTOM | Gravity.START;
11121         lp.format = v.getBackground().getOpacity();
11122         lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
11123                 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
11124         lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
11125         ((WindowManager)mContext.getSystemService(
11126                 Context.WINDOW_SERVICE)).addView(v, lp);
11127     }
11128
11129     public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
11130         if (!(sender instanceof PendingIntentRecord)) {
11131             return;
11132         }
11133         final PendingIntentRecord rec = (PendingIntentRecord)sender;
11134         final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11135         synchronized (stats) {
11136             if (mBatteryStatsService.isOnBattery()) {
11137                 mBatteryStatsService.enforceCallingPermission();
11138                 int MY_UID = Binder.getCallingUid();
11139                 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
11140                 BatteryStatsImpl.Uid.Pkg pkg =
11141                     stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
11142                             sourcePkg != null ? sourcePkg : rec.key.packageName);
11143                 pkg.noteWakeupAlarmLocked(tag);
11144             }
11145         }
11146     }
11147
11148     public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
11149         if (!(sender instanceof PendingIntentRecord)) {
11150             return;
11151         }
11152         final PendingIntentRecord rec = (PendingIntentRecord)sender;
11153         final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11154         synchronized (stats) {
11155             mBatteryStatsService.enforceCallingPermission();
11156             int MY_UID = Binder.getCallingUid();
11157             int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
11158             mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
11159         }
11160     }
11161
11162     public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
11163         if (!(sender instanceof PendingIntentRecord)) {
11164             return;
11165         }
11166         final PendingIntentRecord rec = (PendingIntentRecord)sender;
11167         final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11168         synchronized (stats) {
11169             mBatteryStatsService.enforceCallingPermission();
11170             int MY_UID = Binder.getCallingUid();
11171             int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
11172             mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
11173         }
11174     }
11175
11176     public boolean killPids(int[] pids, String pReason, boolean secure) {
11177         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
11178             throw new SecurityException("killPids only available to the system");
11179         }
11180         String reason = (pReason == null) ? "Unknown" : pReason;
11181         // XXX Note: don't acquire main activity lock here, because the window
11182         // manager calls in with its locks held.
11183
11184         boolean killed = false;
11185         synchronized (mPidsSelfLocked) {
11186             int[] types = new int[pids.length];
11187             int worstType = 0;
11188             for (int i=0; i<pids.length; i++) {
11189                 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
11190                 if (proc != null) {
11191                     int type = proc.setAdj;
11192                     types[i] = type;
11193                     if (type > worstType) {
11194                         worstType = type;
11195                     }
11196                 }
11197             }
11198
11199             // If the worst oom_adj is somewhere in the cached proc LRU range,
11200             // then constrain it so we will kill all cached procs.
11201             if (worstType < ProcessList.CACHED_APP_MAX_ADJ
11202                     && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
11203                 worstType = ProcessList.CACHED_APP_MIN_ADJ;
11204             }
11205
11206             // If this is not a secure call, don't let it kill processes that
11207             // are important.
11208             if (!secure && worstType < ProcessList.SERVICE_ADJ) {
11209                 worstType = ProcessList.SERVICE_ADJ;
11210             }
11211
11212             Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
11213             for (int i=0; i<pids.length; i++) {
11214                 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
11215                 if (proc == null) {
11216                     continue;
11217                 }
11218                 int adj = proc.setAdj;
11219                 if (adj >= worstType && !proc.killedByAm) {
11220                     proc.kill(reason, true);
11221                     killed = true;
11222                 }
11223             }
11224         }
11225         return killed;
11226     }
11227
11228     @Override
11229     public void killUid(int appId, int userId, String reason) {
11230         enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
11231         synchronized (this) {
11232             final long identity = Binder.clearCallingIdentity();
11233             try {
11234                 killPackageProcessesLocked(null, appId, userId,
11235                         ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
11236                         reason != null ? reason : "kill uid");
11237             } finally {
11238                 Binder.restoreCallingIdentity(identity);
11239             }
11240         }
11241     }
11242
11243     @Override
11244     public boolean killProcessesBelowForeground(String reason) {
11245         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
11246             throw new SecurityException("killProcessesBelowForeground() only available to system");
11247         }
11248
11249         return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
11250     }
11251
11252     private boolean killProcessesBelowAdj(int belowAdj, String reason) {
11253         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
11254             throw new SecurityException("killProcessesBelowAdj() only available to system");
11255         }
11256
11257         boolean killed = false;
11258         synchronized (mPidsSelfLocked) {
11259             final int size = mPidsSelfLocked.size();
11260             for (int i = 0; i < size; i++) {
11261                 final int pid = mPidsSelfLocked.keyAt(i);
11262                 final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
11263                 if (proc == null) continue;
11264
11265                 final int adj = proc.setAdj;
11266                 if (adj > belowAdj && !proc.killedByAm) {
11267                     proc.kill(reason, true);
11268                     killed = true;
11269                 }
11270             }
11271         }
11272         return killed;
11273     }
11274
11275     @Override
11276     public void hang(final IBinder who, boolean allowRestart) {
11277         if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
11278                 != PackageManager.PERMISSION_GRANTED) {
11279             throw new SecurityException("Requires permission "
11280                     + android.Manifest.permission.SET_ACTIVITY_WATCHER);
11281         }
11282
11283         final IBinder.DeathRecipient death = new DeathRecipient() {
11284             @Override
11285             public void binderDied() {
11286                 synchronized (this) {
11287                     notifyAll();
11288                 }
11289             }
11290         };
11291
11292         try {
11293             who.linkToDeath(death, 0);
11294         } catch (RemoteException e) {
11295             Slog.w(TAG, "hang: given caller IBinder is already dead.");
11296             return;
11297         }
11298
11299         synchronized (this) {
11300             Watchdog.getInstance().setAllowRestart(allowRestart);
11301             Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
11302             synchronized (death) {
11303                 while (who.isBinderAlive()) {
11304                     try {
11305                         death.wait();
11306                     } catch (InterruptedException e) {
11307                     }
11308                 }
11309             }
11310             Watchdog.getInstance().setAllowRestart(true);
11311         }
11312     }
11313
11314     @Override
11315     public void restart() {
11316         if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
11317                 != PackageManager.PERMISSION_GRANTED) {
11318             throw new SecurityException("Requires permission "
11319                     + android.Manifest.permission.SET_ACTIVITY_WATCHER);
11320         }
11321
11322         Log.i(TAG, "Sending shutdown broadcast...");
11323
11324         BroadcastReceiver br = new BroadcastReceiver() {
11325             @Override public void onReceive(Context context, Intent intent) {
11326                 // Now the broadcast is done, finish up the low-level shutdown.
11327                 Log.i(TAG, "Shutting down activity manager...");
11328                 shutdown(10000);
11329                 Log.i(TAG, "Shutdown complete, restarting!");
11330                 Process.killProcess(Process.myPid());
11331                 System.exit(10);
11332             }
11333         };
11334
11335         // First send the high-level shut down broadcast.
11336         Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
11337         intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
11338         intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
11339         /* For now we are not doing a clean shutdown, because things seem to get unhappy.
11340         mContext.sendOrderedBroadcastAsUser(intent,
11341                 UserHandle.ALL, null, br, mHandler, 0, null, null);
11342         */
11343         br.onReceive(mContext, intent);
11344     }
11345
11346     private long getLowRamTimeSinceIdle(long now) {
11347         return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
11348     }
11349
11350     @Override
11351     public void performIdleMaintenance() {
11352         if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
11353                 != PackageManager.PERMISSION_GRANTED) {
11354             throw new SecurityException("Requires permission "
11355                     + android.Manifest.permission.SET_ACTIVITY_WATCHER);
11356         }
11357
11358         synchronized (this) {
11359             final long now = SystemClock.uptimeMillis();
11360             final long timeSinceLastIdle = now - mLastIdleTime;
11361             final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
11362             mLastIdleTime = now;
11363             mLowRamTimeSinceLastIdle = 0;
11364             if (mLowRamStartTime != 0) {
11365                 mLowRamStartTime = now;
11366             }
11367
11368             StringBuilder sb = new StringBuilder(128);
11369             sb.append("Idle maintenance over ");
11370             TimeUtils.formatDuration(timeSinceLastIdle, sb);
11371             sb.append(" low RAM for ");
11372             TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
11373             Slog.i(TAG, sb.toString());
11374
11375             // If at least 1/3 of our time since the last idle period has been spent
11376             // with RAM low, then we want to kill processes.
11377             boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
11378
11379             for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
11380                 ProcessRecord proc = mLruProcesses.get(i);
11381                 if (proc.notCachedSinceIdle) {
11382                     if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
11383                             && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
11384                             && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
11385                         if (doKilling && proc.initialIdlePss != 0
11386                                 && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
11387                             sb = new StringBuilder(128);
11388                             sb.append("Kill");
11389                             sb.append(proc.processName);
11390                             sb.append(" in idle maint: pss=");
11391                             sb.append(proc.lastPss);
11392                             sb.append(", initialPss=");
11393                             sb.append(proc.initialIdlePss);
11394                             sb.append(", period=");
11395                             TimeUtils.formatDuration(timeSinceLastIdle, sb);
11396                             sb.append(", lowRamPeriod=");
11397                             TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
11398                             Slog.wtfQuiet(TAG, sb.toString());
11399                             proc.kill("idle maint (pss " + proc.lastPss
11400                                     + " from " + proc.initialIdlePss + ")", true);
11401                         }
11402                     }
11403                 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
11404                     proc.notCachedSinceIdle = true;
11405                     proc.initialIdlePss = 0;
11406                     proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
11407                             mTestPssMode, isSleeping(), now);
11408                 }
11409             }
11410
11411             mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
11412             mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
11413         }
11414     }
11415
11416     private void retrieveSettings() {
11417         final ContentResolver resolver = mContext.getContentResolver();
11418         String debugApp = Settings.Global.getString(
11419             resolver, Settings.Global.DEBUG_APP);
11420         boolean waitForDebugger = Settings.Global.getInt(
11421             resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
11422         boolean alwaysFinishActivities = Settings.Global.getInt(
11423             resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
11424         boolean forceRtl = Settings.Global.getInt(
11425                 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
11426         // Transfer any global setting for forcing RTL layout, into a System Property
11427         SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
11428
11429         Configuration configuration = new Configuration();
11430         Settings.System.getConfiguration(resolver, configuration);
11431         if (forceRtl) {
11432             // This will take care of setting the correct layout direction flags
11433             configuration.setLayoutDirection(configuration.locale);
11434         }
11435
11436         synchronized (this) {
11437             mDebugApp = mOrigDebugApp = debugApp;
11438             mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
11439             mAlwaysFinishActivities = alwaysFinishActivities;
11440             // This happens before any activities are started, so we can
11441             // change mConfiguration in-place.
11442             updateConfigurationLocked(configuration, null, false, true);
11443             if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
11444                     "Initial config: " + mConfiguration);
11445         }
11446     }
11447
11448     /** Loads resources after the current configuration has been set. */
11449     private void loadResourcesOnSystemReady() {
11450         final Resources res = mContext.getResources();
11451         mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
11452         mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
11453         mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
11454     }
11455
11456     public boolean testIsSystemReady() {
11457         // no need to synchronize(this) just to read & return the value
11458         return mSystemReady;
11459     }
11460
11461     private static File getCalledPreBootReceiversFile() {
11462         File dataDir = Environment.getDataDirectory();
11463         File systemDir = new File(dataDir, "system");
11464         File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
11465         return fname;
11466     }
11467
11468     private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
11469         ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
11470         File file = getCalledPreBootReceiversFile();
11471         FileInputStream fis = null;
11472         try {
11473             fis = new FileInputStream(file);
11474             DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
11475             int fvers = dis.readInt();
11476             if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
11477                 String vers = dis.readUTF();
11478                 String codename = dis.readUTF();
11479                 String build = dis.readUTF();
11480                 if (android.os.Build.VERSION.RELEASE.equals(vers)
11481                         && android.os.Build.VERSION.CODENAME.equals(codename)
11482                         && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
11483                     int num = dis.readInt();
11484                     while (num > 0) {
11485                         num--;
11486                         String pkg = dis.readUTF();
11487                         String cls = dis.readUTF();
11488                         lastDoneReceivers.add(new ComponentName(pkg, cls));
11489                     }
11490                 }
11491             }
11492         } catch (FileNotFoundException e) {
11493         } catch (IOException e) {
11494             Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
11495         } finally {
11496             if (fis != null) {
11497                 try {
11498                     fis.close();
11499                 } catch (IOException e) {
11500                 }
11501             }
11502         }
11503         return lastDoneReceivers;
11504     }
11505
11506     private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
11507         File file = getCalledPreBootReceiversFile();
11508         FileOutputStream fos = null;
11509         DataOutputStream dos = null;
11510         try {
11511             fos = new FileOutputStream(file);
11512             dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
11513             dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
11514             dos.writeUTF(android.os.Build.VERSION.RELEASE);
11515             dos.writeUTF(android.os.Build.VERSION.CODENAME);
11516             dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
11517             dos.writeInt(list.size());
11518             for (int i=0; i<list.size(); i++) {
11519                 dos.writeUTF(list.get(i).getPackageName());
11520                 dos.writeUTF(list.get(i).getClassName());
11521             }
11522         } catch (IOException e) {
11523             Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
11524             file.delete();
11525         } finally {
11526             FileUtils.sync(fos);
11527             if (dos != null) {
11528                 try {
11529                     dos.close();
11530                 } catch (IOException e) {
11531                     // TODO Auto-generated catch block
11532                     e.printStackTrace();
11533                 }
11534             }
11535         }
11536     }
11537
11538     final class PreBootContinuation extends IIntentReceiver.Stub {
11539         final Intent intent;
11540         final Runnable onFinishCallback;
11541         final ArrayList<ComponentName> doneReceivers;
11542         final List<ResolveInfo> ris;
11543         final int[] users;
11544         int lastRi = -1;
11545         int curRi = 0;
11546         int curUser = 0;
11547
11548         PreBootContinuation(Intent _intent, Runnable _onFinishCallback,
11549                 ArrayList<ComponentName> _doneReceivers, List<ResolveInfo> _ris, int[] _users) {
11550             intent = _intent;
11551             onFinishCallback = _onFinishCallback;
11552             doneReceivers = _doneReceivers;
11553             ris = _ris;
11554             users = _users;
11555         }
11556
11557         void go() {
11558             if (lastRi != curRi) {
11559                 ActivityInfo ai = ris.get(curRi).activityInfo;
11560                 ComponentName comp = new ComponentName(ai.packageName, ai.name);
11561                 intent.setComponent(comp);
11562                 doneReceivers.add(comp);
11563                 lastRi = curRi;
11564                 CharSequence label = ai.loadLabel(mContext.getPackageManager());
11565                 showBootMessage(mContext.getString(R.string.android_preparing_apk, label), false);
11566             }
11567             Slog.i(TAG, "Pre-boot of " + intent.getComponent().toShortString()
11568                     + " for user " + users[curUser]);
11569             EventLogTags.writeAmPreBoot(users[curUser], intent.getComponent().getPackageName());
11570             broadcastIntentLocked(null, null, intent, null, this,
11571                     0, null, null, null, AppOpsManager.OP_NONE,
11572                     null, true, false, MY_PID, Process.SYSTEM_UID, users[curUser]);
11573         }
11574
11575         public void performReceive(Intent intent, int resultCode,
11576                 String data, Bundle extras, boolean ordered,
11577                 boolean sticky, int sendingUser) {
11578             curUser++;
11579             if (curUser >= users.length) {
11580                 curUser = 0;
11581                 curRi++;
11582                 if (curRi >= ris.size()) {
11583                     // All done sending broadcasts!
11584                     if (onFinishCallback != null) {
11585                         // The raw IIntentReceiver interface is called
11586                         // with the AM lock held, so redispatch to
11587                         // execute our code without the lock.
11588                         mHandler.post(onFinishCallback);
11589                     }
11590                     return;
11591                 }
11592             }
11593             go();
11594         }
11595     }
11596
11597     private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
11598             ArrayList<ComponentName> doneReceivers, int userId) {
11599         Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
11600         List<ResolveInfo> ris = null;
11601         try {
11602             ris = AppGlobals.getPackageManager().queryIntentReceivers(
11603                     intent, null, 0, userId);
11604         } catch (RemoteException e) {
11605         }
11606         if (ris == null) {
11607             return false;
11608         }
11609         for (int i=ris.size()-1; i>=0; i--) {
11610             if ((ris.get(i).activityInfo.applicationInfo.flags
11611                     &ApplicationInfo.FLAG_SYSTEM) == 0) {
11612                 ris.remove(i);
11613             }
11614         }
11615         intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
11616
11617         // For User 0, load the version number. When delivering to a new user, deliver
11618         // to all receivers.
11619         if (userId == UserHandle.USER_OWNER) {
11620             ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
11621             for (int i=0; i<ris.size(); i++) {
11622                 ActivityInfo ai = ris.get(i).activityInfo;
11623                 ComponentName comp = new ComponentName(ai.packageName, ai.name);
11624                 if (lastDoneReceivers.contains(comp)) {
11625                     // We already did the pre boot receiver for this app with the current
11626                     // platform version, so don't do it again...
11627                     ris.remove(i);
11628                     i--;
11629                     // ...however, do keep it as one that has been done, so we don't
11630                     // forget about it when rewriting the file of last done receivers.
11631                     doneReceivers.add(comp);
11632                 }
11633             }
11634         }
11635
11636         if (ris.size() <= 0) {
11637             return false;
11638         }
11639
11640         // If primary user, send broadcast to all available users, else just to userId
11641         final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
11642                 : new int[] { userId };
11643         if (users.length <= 0) {
11644             return false;
11645         }
11646
11647         PreBootContinuation cont = new PreBootContinuation(intent, onFinishCallback, doneReceivers,
11648                 ris, users);
11649         cont.go();
11650         return true;
11651     }
11652
11653     public void systemReady(final Runnable goingCallback) {
11654         synchronized(this) {
11655             if (mSystemReady) {
11656                 // If we're done calling all the receivers, run the next "boot phase" passed in
11657                 // by the SystemServer
11658                 if (goingCallback != null) {
11659                     goingCallback.run();
11660                 }
11661                 return;
11662             }
11663
11664             mLocalDeviceIdleController
11665                     = LocalServices.getService(DeviceIdleController.LocalService.class);
11666
11667             // Make sure we have the current profile info, since it is needed for
11668             // security checks.
11669             updateCurrentProfileIdsLocked();
11670
11671             mRecentTasks.clear();
11672             mRecentTasks.addAll(mTaskPersister.restoreTasksLocked());
11673             mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
11674             mTaskPersister.startPersisting();
11675
11676             // Check to see if there are any update receivers to run.
11677             if (!mDidUpdate) {
11678                 if (mWaitingUpdate) {
11679                     return;
11680                 }
11681                 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
11682                 mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
11683                     public void run() {
11684                         synchronized (ActivityManagerService.this) {
11685                             mDidUpdate = true;
11686                         }
11687                         showBootMessage(mContext.getText(
11688                                 R.string.android_upgrading_complete),
11689                                 false);
11690                         writeLastDonePreBootReceivers(doneReceivers);
11691                         systemReady(goingCallback);
11692                     }
11693                 }, doneReceivers, UserHandle.USER_OWNER);
11694
11695                 if (mWaitingUpdate) {
11696                     return;
11697                 }
11698                 mDidUpdate = true;
11699             }
11700
11701             mAppOpsService.systemReady();
11702             mSystemReady = true;
11703         }
11704
11705         ArrayList<ProcessRecord> procsToKill = null;
11706         synchronized(mPidsSelfLocked) {
11707             for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
11708                 ProcessRecord proc = mPidsSelfLocked.valueAt(i);
11709                 if (!isAllowedWhileBooting(proc.info)){
11710                     if (procsToKill == null) {
11711                         procsToKill = new ArrayList<ProcessRecord>();
11712                     }
11713                     procsToKill.add(proc);
11714                 }
11715             }
11716         }
11717
11718         synchronized(this) {
11719             if (procsToKill != null) {
11720                 for (int i=procsToKill.size()-1; i>=0; i--) {
11721                     ProcessRecord proc = procsToKill.get(i);
11722                     Slog.i(TAG, "Removing system update proc: " + proc);
11723                     removeProcessLocked(proc, true, false, "system update done");
11724                 }
11725             }
11726
11727             // Now that we have cleaned up any update processes, we
11728             // are ready to start launching real processes and know that
11729             // we won't trample on them any more.
11730             mProcessesReady = true;
11731         }
11732
11733         Slog.i(TAG, "System now ready");
11734         EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
11735             SystemClock.uptimeMillis());
11736
11737         synchronized(this) {
11738             // Make sure we have no pre-ready processes sitting around.
11739
11740             if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11741                 ResolveInfo ri = mContext.getPackageManager()
11742                         .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
11743                                 STOCK_PM_FLAGS);
11744                 CharSequence errorMsg = null;
11745                 if (ri != null) {
11746                     ActivityInfo ai = ri.activityInfo;
11747                     ApplicationInfo app = ai.applicationInfo;
11748                     if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
11749                         mTopAction = Intent.ACTION_FACTORY_TEST;
11750                         mTopData = null;
11751                         mTopComponent = new ComponentName(app.packageName,
11752                                 ai.name);
11753                     } else {
11754                         errorMsg = mContext.getResources().getText(
11755                                 com.android.internal.R.string.factorytest_not_system);
11756                     }
11757                 } else {
11758                     errorMsg = mContext.getResources().getText(
11759                             com.android.internal.R.string.factorytest_no_action);
11760                 }
11761                 if (errorMsg != null) {
11762                     mTopAction = null;
11763                     mTopData = null;
11764                     mTopComponent = null;
11765                     Message msg = Message.obtain();
11766                     msg.what = SHOW_FACTORY_ERROR_MSG;
11767                     msg.getData().putCharSequence("msg", errorMsg);
11768                     mUiHandler.sendMessage(msg);
11769                 }
11770             }
11771         }
11772
11773         retrieveSettings();
11774         loadResourcesOnSystemReady();
11775
11776         synchronized (this) {
11777             readGrantedUriPermissionsLocked();
11778         }
11779
11780         if (goingCallback != null) goingCallback.run();
11781
11782         mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
11783                 Integer.toString(mCurrentUserId), mCurrentUserId);
11784         mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
11785                 Integer.toString(mCurrentUserId), mCurrentUserId);
11786         mSystemServiceManager.startUser(mCurrentUserId);
11787
11788         synchronized (this) {
11789             if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11790                 try {
11791                     List apps = AppGlobals.getPackageManager().
11792                         getPersistentApplications(STOCK_PM_FLAGS);
11793                     if (apps != null) {
11794                         int N = apps.size();
11795                         int i;
11796                         for (i=0; i<N; i++) {
11797                             ApplicationInfo info
11798                                 = (ApplicationInfo)apps.get(i);
11799                             if (info != null &&
11800                                     !info.packageName.equals("android")) {
11801                                 addAppLocked(info, false, null /* ABI override */);
11802                             }
11803                         }
11804                     }
11805                 } catch (RemoteException ex) {
11806                     // pm is in same process, this will never happen.
11807                 }
11808             }
11809
11810             // Start up initial activity.
11811             mBooting = true;
11812             startHomeActivityLocked(mCurrentUserId, "systemReady");
11813
11814             try {
11815                 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
11816                     Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
11817                             + " data partition or your device will be unstable.");
11818                     mUiHandler.obtainMessage(SHOW_UID_ERROR_MSG).sendToTarget();
11819                 }
11820             } catch (RemoteException e) {
11821             }
11822
11823             if (!Build.isBuildConsistent()) {
11824                 Slog.e(TAG, "Build fingerprint is not consistent, warning user");
11825                 mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_MSG).sendToTarget();
11826             }
11827
11828             long ident = Binder.clearCallingIdentity();
11829             try {
11830                 Intent intent = new Intent(Intent.ACTION_USER_STARTED);
11831                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
11832                         | Intent.FLAG_RECEIVER_FOREGROUND);
11833                 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11834                 broadcastIntentLocked(null, null, intent,
11835                         null, null, 0, null, null, null, AppOpsManager.OP_NONE,
11836                         null, false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
11837                 intent = new Intent(Intent.ACTION_USER_STARTING);
11838                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11839                 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11840                 broadcastIntentLocked(null, null, intent,
11841                         null, new IIntentReceiver.Stub() {
11842                             @Override
11843                             public void performReceive(Intent intent, int resultCode, String data,
11844                                     Bundle extras, boolean ordered, boolean sticky, int sendingUser)
11845                                     throws RemoteException {
11846                             }
11847                         }, 0, null, null,
11848                         new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
11849                         null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
11850             } catch (Throwable t) {
11851                 Slog.wtf(TAG, "Failed sending first user broadcasts", t);
11852             } finally {
11853                 Binder.restoreCallingIdentity(ident);
11854             }
11855             mStackSupervisor.resumeTopActivitiesLocked();
11856             sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
11857         }
11858     }
11859
11860     private boolean makeAppCrashingLocked(ProcessRecord app,
11861             String shortMsg, String longMsg, String stackTrace) {
11862         app.crashing = true;
11863         app.crashingReport = generateProcessError(app,
11864                 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
11865         startAppProblemLocked(app);
11866         app.stopFreezingAllLocked();
11867         return handleAppCrashLocked(app, "force-crash" /*reason*/, shortMsg, longMsg, stackTrace);
11868     }
11869
11870     private void makeAppNotRespondingLocked(ProcessRecord app,
11871             String activity, String shortMsg, String longMsg) {
11872         app.notResponding = true;
11873         app.notRespondingReport = generateProcessError(app,
11874                 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
11875                 activity, shortMsg, longMsg, null);
11876         startAppProblemLocked(app);
11877         app.stopFreezingAllLocked();
11878     }
11879
11880     /**
11881      * Generate a process error record, suitable for attachment to a ProcessRecord.
11882      *
11883      * @param app The ProcessRecord in which the error occurred.
11884      * @param condition Crashing, Application Not Responding, etc.  Values are defined in
11885      *                      ActivityManager.AppErrorStateInfo
11886      * @param activity The activity associated with the crash, if known.
11887      * @param shortMsg Short message describing the crash.
11888      * @param longMsg Long message describing the crash.
11889      * @param stackTrace Full crash stack trace, may be null.
11890      *
11891      * @return Returns a fully-formed AppErrorStateInfo record.
11892      */
11893     private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
11894             int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
11895         ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
11896
11897         report.condition = condition;
11898         report.processName = app.processName;
11899         report.pid = app.pid;
11900         report.uid = app.info.uid;
11901         report.tag = activity;
11902         report.shortMsg = shortMsg;
11903         report.longMsg = longMsg;
11904         report.stackTrace = stackTrace;
11905
11906         return report;
11907     }
11908
11909     void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
11910         synchronized (this) {
11911             app.crashing = false;
11912             app.crashingReport = null;
11913             app.notResponding = false;
11914             app.notRespondingReport = null;
11915             if (app.anrDialog == fromDialog) {
11916                 app.anrDialog = null;
11917             }
11918             if (app.waitDialog == fromDialog) {
11919                 app.waitDialog = null;
11920             }
11921             if (app.pid > 0 && app.pid != MY_PID) {
11922                 handleAppCrashLocked(app, "user-terminated" /*reason*/,
11923                         null /*shortMsg*/, null /*longMsg*/, null /*stackTrace*/);
11924                 app.kill("user request after error", true);
11925             }
11926         }
11927     }
11928
11929     private boolean handleAppCrashLocked(ProcessRecord app, String reason,
11930             String shortMsg, String longMsg, String stackTrace) {
11931         long now = SystemClock.uptimeMillis();
11932
11933         Long crashTime;
11934         if (!app.isolated) {
11935             crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
11936         } else {
11937             crashTime = null;
11938         }
11939         if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
11940             // This process loses!
11941             Slog.w(TAG, "Process " + app.info.processName
11942                     + " has crashed too many times: killing!");
11943             EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
11944                     app.userId, app.info.processName, app.uid);
11945             mStackSupervisor.handleAppCrashLocked(app);
11946             if (!app.persistent) {
11947                 // We don't want to start this process again until the user
11948                 // explicitly does so...  but for persistent process, we really
11949                 // need to keep it running.  If a persistent process is actually
11950                 // repeatedly crashing, then badness for everyone.
11951                 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
11952                         app.info.processName);
11953                 if (!app.isolated) {
11954                     // XXX We don't have a way to mark isolated processes
11955                     // as bad, since they don't have a peristent identity.
11956                     mBadProcesses.put(app.info.processName, app.uid,
11957                             new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
11958                     mProcessCrashTimes.remove(app.info.processName, app.uid);
11959                 }
11960                 app.bad = true;
11961                 app.removed = true;
11962                 // Don't let services in this process be restarted and potentially
11963                 // annoy the user repeatedly.  Unless it is persistent, since those
11964                 // processes run critical code.
11965                 removeProcessLocked(app, false, false, "crash");
11966                 mStackSupervisor.resumeTopActivitiesLocked();
11967                 return false;
11968             }
11969             mStackSupervisor.resumeTopActivitiesLocked();
11970         } else {
11971             mStackSupervisor.finishTopRunningActivityLocked(app, reason);
11972         }
11973
11974         // Bump up the crash count of any services currently running in the proc.
11975         for (int i=app.services.size()-1; i>=0; i--) {
11976             // Any services running in the application need to be placed
11977             // back in the pending list.
11978             ServiceRecord sr = app.services.valueAt(i);
11979             sr.crashCount++;
11980         }
11981
11982         // If the crashing process is what we consider to be the "home process" and it has been
11983         // replaced by a third-party app, clear the package preferred activities from packages
11984         // with a home activity running in the process to prevent a repeatedly crashing app
11985         // from blocking the user to manually clear the list.
11986         final ArrayList<ActivityRecord> activities = app.activities;
11987         if (app == mHomeProcess && activities.size() > 0
11988                     && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
11989             for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
11990                 final ActivityRecord r = activities.get(activityNdx);
11991                 if (r.isHomeActivity()) {
11992                     Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
11993                     try {
11994                         ActivityThread.getPackageManager()
11995                                 .clearPackagePreferredActivities(r.packageName);
11996                     } catch (RemoteException c) {
11997                         // pm is in same process, this will never happen.
11998                     }
11999                 }
12000             }
12001         }
12002
12003         if (!app.isolated) {
12004             // XXX Can't keep track of crash times for isolated processes,
12005             // because they don't have a perisistent identity.
12006             mProcessCrashTimes.put(app.info.processName, app.uid, now);
12007         }
12008
12009         if (app.crashHandler != null) mHandler.post(app.crashHandler);
12010         return true;
12011     }
12012
12013     void startAppProblemLocked(ProcessRecord app) {
12014         // If this app is not running under the current user, then we
12015         // can't give it a report button because that would require
12016         // launching the report UI under a different user.
12017         app.errorReportReceiver = null;
12018
12019         for (int userId : mCurrentProfileIds) {
12020             if (app.userId == userId) {
12021                 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
12022                         mContext, app.info.packageName, app.info.flags);
12023             }
12024         }
12025         skipCurrentReceiverLocked(app);
12026     }
12027
12028     void skipCurrentReceiverLocked(ProcessRecord app) {
12029         for (BroadcastQueue queue : mBroadcastQueues) {
12030             queue.skipCurrentReceiverLocked(app);
12031         }
12032     }
12033
12034     /**
12035      * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
12036      * The application process will exit immediately after this call returns.
12037      * @param app object of the crashing app, null for the system server
12038      * @param crashInfo describing the exception
12039      */
12040     public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
12041         ProcessRecord r = findAppProcess(app, "Crash");
12042         final String processName = app == null ? "system_server"
12043                 : (r == null ? "unknown" : r.processName);
12044
12045         handleApplicationCrashInner("crash", r, processName, crashInfo);
12046     }
12047
12048     /* Native crash reporting uses this inner version because it needs to be somewhat
12049      * decoupled from the AM-managed cleanup lifecycle
12050      */
12051     void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
12052             ApplicationErrorReport.CrashInfo crashInfo) {
12053         EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
12054                 UserHandle.getUserId(Binder.getCallingUid()), processName,
12055                 r == null ? -1 : r.info.flags,
12056                 crashInfo.exceptionClassName,
12057                 crashInfo.exceptionMessage,
12058                 crashInfo.throwFileName,
12059                 crashInfo.throwLineNumber);
12060
12061         addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
12062
12063         crashApplication(r, crashInfo);
12064     }
12065
12066     public void handleApplicationStrictModeViolation(
12067             IBinder app,
12068             int violationMask,
12069             StrictMode.ViolationInfo info) {
12070         ProcessRecord r = findAppProcess(app, "StrictMode");
12071         if (r == null) {
12072             return;
12073         }
12074
12075         if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
12076             Integer stackFingerprint = info.hashCode();
12077             boolean logIt = true;
12078             synchronized (mAlreadyLoggedViolatedStacks) {
12079                 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
12080                     logIt = false;
12081                     // TODO: sub-sample into EventLog for these, with
12082                     // the info.durationMillis?  Then we'd get
12083                     // the relative pain numbers, without logging all
12084                     // the stack traces repeatedly.  We'd want to do
12085                     // likewise in the client code, which also does
12086                     // dup suppression, before the Binder call.
12087                 } else {
12088                     if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
12089                         mAlreadyLoggedViolatedStacks.clear();
12090                     }
12091                     mAlreadyLoggedViolatedStacks.add(stackFingerprint);
12092                 }
12093             }
12094             if (logIt) {
12095                 logStrictModeViolationToDropBox(r, info);
12096             }
12097         }
12098
12099         if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
12100             AppErrorResult result = new AppErrorResult();
12101             synchronized (this) {
12102                 final long origId = Binder.clearCallingIdentity();
12103
12104                 Message msg = Message.obtain();
12105                 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
12106                 HashMap<String, Object> data = new HashMap<String, Object>();
12107                 data.put("result", result);
12108                 data.put("app", r);
12109                 data.put("violationMask", violationMask);
12110                 data.put("info", info);
12111                 msg.obj = data;
12112                 mUiHandler.sendMessage(msg);
12113
12114                 Binder.restoreCallingIdentity(origId);
12115             }
12116             int res = result.get();
12117             Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
12118         }
12119     }
12120
12121     // Depending on the policy in effect, there could be a bunch of
12122     // these in quick succession so we try to batch these together to
12123     // minimize disk writes, number of dropbox entries, and maximize
12124     // compression, by having more fewer, larger records.
12125     private void logStrictModeViolationToDropBox(
12126             ProcessRecord process,
12127             StrictMode.ViolationInfo info) {
12128         if (info == null) {
12129             return;
12130         }
12131         final boolean isSystemApp = process == null ||
12132                 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
12133                                        ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
12134         final String processName = process == null ? "unknown" : process.processName;
12135         final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
12136         final DropBoxManager dbox = (DropBoxManager)
12137                 mContext.getSystemService(Context.DROPBOX_SERVICE);
12138
12139         // Exit early if the dropbox isn't configured to accept this report type.
12140         if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
12141
12142         boolean bufferWasEmpty;
12143         boolean needsFlush;
12144         final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
12145         synchronized (sb) {
12146             bufferWasEmpty = sb.length() == 0;
12147             appendDropBoxProcessHeaders(process, processName, sb);
12148             sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
12149             sb.append("System-App: ").append(isSystemApp).append("\n");
12150             sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
12151             if (info.violationNumThisLoop != 0) {
12152                 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
12153             }
12154             if (info.numAnimationsRunning != 0) {
12155                 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
12156             }
12157             if (info.broadcastIntentAction != null) {
12158                 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
12159             }
12160             if (info.durationMillis != -1) {
12161                 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
12162             }
12163             if (info.numInstances != -1) {
12164                 sb.append("Instance-Count: ").append(info.numInstances).append("\n");
12165             }
12166             if (info.tags != null) {
12167                 for (String tag : info.tags) {
12168                     sb.append("Span-Tag: ").append(tag).append("\n");
12169                 }
12170             }
12171             sb.append("\n");
12172             if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
12173                 sb.append(info.crashInfo.stackTrace);
12174                 sb.append("\n");
12175             }
12176             if (info.message != null) {
12177                 sb.append(info.message);
12178                 sb.append("\n");
12179             }
12180
12181             // Only buffer up to ~64k.  Various logging bits truncate
12182             // things at 128k.
12183             needsFlush = (sb.length() > 64 * 1024);
12184         }
12185
12186         // Flush immediately if the buffer's grown too large, or this
12187         // is a non-system app.  Non-system apps are isolated with a
12188         // different tag & policy and not batched.
12189         //
12190         // Batching is useful during internal testing with
12191         // StrictMode settings turned up high.  Without batching,
12192         // thousands of separate files could be created on boot.
12193         if (!isSystemApp || needsFlush) {
12194             new Thread("Error dump: " + dropboxTag) {
12195                 @Override
12196                 public void run() {
12197                     String report;
12198                     synchronized (sb) {
12199                         report = sb.toString();
12200                         sb.delete(0, sb.length());
12201                         sb.trimToSize();
12202                     }
12203                     if (report.length() != 0) {
12204                         dbox.addText(dropboxTag, report);
12205                     }
12206                 }
12207             }.start();
12208             return;
12209         }
12210
12211         // System app batching:
12212         if (!bufferWasEmpty) {
12213             // An existing dropbox-writing thread is outstanding, so
12214             // we don't need to start it up.  The existing thread will
12215             // catch the buffer appends we just did.
12216             return;
12217         }
12218
12219         // Worker thread to both batch writes and to avoid blocking the caller on I/O.
12220         // (After this point, we shouldn't access AMS internal data structures.)
12221         new Thread("Error dump: " + dropboxTag) {
12222             @Override
12223             public void run() {
12224                 // 5 second sleep to let stacks arrive and be batched together
12225                 try {
12226                     Thread.sleep(5000);  // 5 seconds
12227                 } catch (InterruptedException e) {}
12228
12229                 String errorReport;
12230                 synchronized (mStrictModeBuffer) {
12231                     errorReport = mStrictModeBuffer.toString();
12232                     if (errorReport.length() == 0) {
12233                         return;
12234                     }
12235                     mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
12236                     mStrictModeBuffer.trimToSize();
12237                 }
12238                 dbox.addText(dropboxTag, errorReport);
12239             }
12240         }.start();
12241     }
12242
12243     /**
12244      * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
12245      * @param app object of the crashing app, null for the system server
12246      * @param tag reported by the caller
12247      * @param system whether this wtf is coming from the system
12248      * @param crashInfo describing the context of the error
12249      * @return true if the process should exit immediately (WTF is fatal)
12250      */
12251     public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
12252             final ApplicationErrorReport.CrashInfo crashInfo) {
12253         final int callingUid = Binder.getCallingUid();
12254         final int callingPid = Binder.getCallingPid();
12255
12256         if (system) {
12257             // If this is coming from the system, we could very well have low-level
12258             // system locks held, so we want to do this all asynchronously.  And we
12259             // never want this to become fatal, so there is that too.
12260             mHandler.post(new Runnable() {
12261                 @Override public void run() {
12262                     handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
12263                 }
12264             });
12265             return false;
12266         }
12267
12268         final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
12269                 crashInfo);
12270
12271         if (r != null && r.pid != Process.myPid() &&
12272                 Settings.Global.getInt(mContext.getContentResolver(),
12273                         Settings.Global.WTF_IS_FATAL, 0) != 0) {
12274             crashApplication(r, crashInfo);
12275             return true;
12276         } else {
12277             return false;
12278         }
12279     }
12280
12281     ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
12282             final ApplicationErrorReport.CrashInfo crashInfo) {
12283         final ProcessRecord r = findAppProcess(app, "WTF");
12284         final String processName = app == null ? "system_server"
12285                 : (r == null ? "unknown" : r.processName);
12286
12287         EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
12288                 processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
12289
12290         addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
12291
12292         return r;
12293     }
12294
12295     /**
12296      * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
12297      * @return the corresponding {@link ProcessRecord} object, or null if none could be found
12298      */
12299     private ProcessRecord findAppProcess(IBinder app, String reason) {
12300         if (app == null) {
12301             return null;
12302         }
12303
12304         synchronized (this) {
12305             final int NP = mProcessNames.getMap().size();
12306             for (int ip=0; ip<NP; ip++) {
12307                 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
12308                 final int NA = apps.size();
12309                 for (int ia=0; ia<NA; ia++) {
12310                     ProcessRecord p = apps.valueAt(ia);
12311                     if (p.thread != null && p.thread.asBinder() == app) {
12312                         return p;
12313                     }
12314                 }
12315             }
12316
12317             Slog.w(TAG, "Can't find mystery application for " + reason
12318                     + " from pid=" + Binder.getCallingPid()
12319                     + " uid=" + Binder.getCallingUid() + ": " + app);
12320             return null;
12321         }
12322     }
12323
12324     /**
12325      * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
12326      * to append various headers to the dropbox log text.
12327      */
12328     private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
12329             StringBuilder sb) {
12330         // Watchdog thread ends up invoking this function (with
12331         // a null ProcessRecord) to add the stack file to dropbox.
12332         // Do not acquire a lock on this (am) in such cases, as it
12333         // could cause a potential deadlock, if and when watchdog
12334         // is invoked due to unavailability of lock on am and it
12335         // would prevent watchdog from killing system_server.
12336         if (process == null) {
12337             sb.append("Process: ").append(processName).append("\n");
12338             return;
12339         }
12340         // Note: ProcessRecord 'process' is guarded by the service
12341         // instance.  (notably process.pkgList, which could otherwise change
12342         // concurrently during execution of this method)
12343         synchronized (this) {
12344             sb.append("Process: ").append(processName).append("\n");
12345             int flags = process.info.flags;
12346             IPackageManager pm = AppGlobals.getPackageManager();
12347             sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
12348             for (int ip=0; ip<process.pkgList.size(); ip++) {
12349                 String pkg = process.pkgList.keyAt(ip);
12350                 sb.append("Package: ").append(pkg);
12351                 try {
12352                     PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
12353                     if (pi != null) {
12354                         sb.append(" v").append(pi.versionCode);
12355                         if (pi.versionName != null) {
12356                             sb.append(" (").append(pi.versionName).append(")");
12357                         }
12358                     }
12359                 } catch (RemoteException e) {
12360                     Slog.e(TAG, "Error getting package info: " + pkg, e);
12361                 }
12362                 sb.append("\n");
12363             }
12364         }
12365     }
12366
12367     private static String processClass(ProcessRecord process) {
12368         if (process == null || process.pid == MY_PID) {
12369             return "system_server";
12370         } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
12371             return "system_app";
12372         } else {
12373             return "data_app";
12374         }
12375     }
12376
12377     /**
12378      * Write a description of an error (crash, WTF, ANR) to the drop box.
12379      * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
12380      * @param process which caused the error, null means the system server
12381      * @param activity which triggered the error, null if unknown
12382      * @param parent activity related to the error, null if unknown
12383      * @param subject line related to the error, null if absent
12384      * @param report in long form describing the error, null if absent
12385      * @param logFile to include in the report, null if none
12386      * @param crashInfo giving an application stack trace, null if absent
12387      */
12388     public void addErrorToDropBox(String eventType,
12389             ProcessRecord process, String processName, ActivityRecord activity,
12390             ActivityRecord parent, String subject,
12391             final String report, final File logFile,
12392             final ApplicationErrorReport.CrashInfo crashInfo) {
12393         // NOTE -- this must never acquire the ActivityManagerService lock,
12394         // otherwise the watchdog may be prevented from resetting the system.
12395
12396         final String dropboxTag = processClass(process) + "_" + eventType;
12397         final DropBoxManager dbox = (DropBoxManager)
12398                 mContext.getSystemService(Context.DROPBOX_SERVICE);
12399
12400         // Exit early if the dropbox isn't configured to accept this report type.
12401         if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
12402
12403         final StringBuilder sb = new StringBuilder(1024);
12404         appendDropBoxProcessHeaders(process, processName, sb);
12405         if (activity != null) {
12406             sb.append("Activity: ").append(activity.shortComponentName).append("\n");
12407         }
12408         if (parent != null && parent.app != null && parent.app.pid != process.pid) {
12409             sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
12410         }
12411         if (parent != null && parent != activity) {
12412             sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
12413         }
12414         if (subject != null) {
12415             sb.append("Subject: ").append(subject).append("\n");
12416         }
12417         sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
12418         if (Debug.isDebuggerConnected()) {
12419             sb.append("Debugger: Connected\n");
12420         }
12421         sb.append("\n");
12422
12423         // Do the rest in a worker thread to avoid blocking the caller on I/O
12424         // (After this point, we shouldn't access AMS internal data structures.)
12425         Thread worker = new Thread("Error dump: " + dropboxTag) {
12426             @Override
12427             public void run() {
12428                 if (report != null) {
12429                     sb.append(report);
12430                 }
12431                 if (logFile != null) {
12432                     try {
12433                         sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
12434                                     "\n\n[[TRUNCATED]]"));
12435                     } catch (IOException e) {
12436                         Slog.e(TAG, "Error reading " + logFile, e);
12437                     }
12438                 }
12439                 if (crashInfo != null && crashInfo.stackTrace != null) {
12440                     sb.append(crashInfo.stackTrace);
12441                 }
12442
12443                 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
12444                 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
12445                 if (lines > 0) {
12446                     sb.append("\n");
12447
12448                     // Merge several logcat streams, and take the last N lines
12449                     InputStreamReader input = null;
12450                     try {
12451                         java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
12452                                 "-v", "time", "-b", "events", "-b", "system", "-b", "main",
12453                                 "-b", "crash",
12454                                 "-t", String.valueOf(lines)).redirectErrorStream(true).start();
12455
12456                         try { logcat.getOutputStream().close(); } catch (IOException e) {}
12457                         try { logcat.getErrorStream().close(); } catch (IOException e) {}
12458                         input = new InputStreamReader(logcat.getInputStream());
12459
12460                         int num;
12461                         char[] buf = new char[8192];
12462                         while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
12463                     } catch (IOException e) {
12464                         Slog.e(TAG, "Error running logcat", e);
12465                     } finally {
12466                         if (input != null) try { input.close(); } catch (IOException e) {}
12467                     }
12468                 }
12469
12470                 dbox.addText(dropboxTag, sb.toString());
12471             }
12472         };
12473
12474         if (process == null) {
12475             // If process is null, we are being called from some internal code
12476             // and may be about to die -- run this synchronously.
12477             worker.run();
12478         } else {
12479             worker.start();
12480         }
12481     }
12482
12483     /**
12484      * Bring up the "unexpected error" dialog box for a crashing app.
12485      * Deal with edge cases (intercepts from instrumented applications,
12486      * ActivityController, error intent receivers, that sort of thing).
12487      * @param r the application crashing
12488      * @param crashInfo describing the failure
12489      */
12490     private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
12491         long timeMillis = System.currentTimeMillis();
12492         String shortMsg = crashInfo.exceptionClassName;
12493         String longMsg = crashInfo.exceptionMessage;
12494         String stackTrace = crashInfo.stackTrace;
12495         if (shortMsg != null && longMsg != null) {
12496             longMsg = shortMsg + ": " + longMsg;
12497         } else if (shortMsg != null) {
12498             longMsg = shortMsg;
12499         }
12500
12501         AppErrorResult result = new AppErrorResult();
12502         synchronized (this) {
12503             if (mController != null) {
12504                 try {
12505                     String name = r != null ? r.processName : null;
12506                     int pid = r != null ? r.pid : Binder.getCallingPid();
12507                     int uid = r != null ? r.info.uid : Binder.getCallingUid();
12508                     if (!mController.appCrashed(name, pid,
12509                             shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
12510                         if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
12511                                 && "Native crash".equals(crashInfo.exceptionClassName)) {
12512                             Slog.w(TAG, "Skip killing native crashed app " + name
12513                                     + "(" + pid + ") during testing");
12514                         } else {
12515                             Slog.w(TAG, "Force-killing crashed app " + name
12516                                     + " at watcher's request");
12517                             if (r != null) {
12518                                 r.kill("crash", true);
12519                             } else {
12520                                 // Huh.
12521                                 Process.killProcess(pid);
12522                                 killProcessGroup(uid, pid);
12523                             }
12524                         }
12525                         return;
12526                     }
12527                 } catch (RemoteException e) {
12528                     mController = null;
12529                     Watchdog.getInstance().setActivityController(null);
12530                 }
12531             }
12532
12533             final long origId = Binder.clearCallingIdentity();
12534
12535             // If this process is running instrumentation, finish it.
12536             if (r != null && r.instrumentationClass != null) {
12537                 Slog.w(TAG, "Error in app " + r.processName
12538                       + " running instrumentation " + r.instrumentationClass + ":");
12539                 if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
12540                 if (longMsg != null) Slog.w(TAG, "  " + longMsg);
12541                 Bundle info = new Bundle();
12542                 info.putString("shortMsg", shortMsg);
12543                 info.putString("longMsg", longMsg);
12544                 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
12545                 Binder.restoreCallingIdentity(origId);
12546                 return;
12547             }
12548
12549             // Log crash in battery stats.
12550             if (r != null) {
12551                 mBatteryStatsService.noteProcessCrash(r.processName, r.uid);
12552             }
12553
12554             // If we can't identify the process or it's already exceeded its crash quota,
12555             // quit right away without showing a crash dialog.
12556             if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
12557                 Binder.restoreCallingIdentity(origId);
12558                 return;
12559             }
12560
12561             Message msg = Message.obtain();
12562             msg.what = SHOW_ERROR_MSG;
12563             HashMap data = new HashMap();
12564             data.put("result", result);
12565             data.put("app", r);
12566             msg.obj = data;
12567             mUiHandler.sendMessage(msg);
12568
12569             Binder.restoreCallingIdentity(origId);
12570         }
12571
12572         int res = result.get();
12573
12574         Intent appErrorIntent = null;
12575         synchronized (this) {
12576             if (r != null && !r.isolated) {
12577                 // XXX Can't keep track of crash time for isolated processes,
12578                 // since they don't have a persistent identity.
12579                 mProcessCrashTimes.put(r.info.processName, r.uid,
12580                         SystemClock.uptimeMillis());
12581             }
12582             if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
12583                 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
12584             }
12585         }
12586
12587         if (appErrorIntent != null) {
12588             try {
12589                 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
12590             } catch (ActivityNotFoundException e) {
12591                 Slog.w(TAG, "bug report receiver dissappeared", e);
12592             }
12593         }
12594     }
12595
12596     Intent createAppErrorIntentLocked(ProcessRecord r,
12597             long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12598         ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
12599         if (report == null) {
12600             return null;
12601         }
12602         Intent result = new Intent(Intent.ACTION_APP_ERROR);
12603         result.setComponent(r.errorReportReceiver);
12604         result.putExtra(Intent.EXTRA_BUG_REPORT, report);
12605         result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
12606         return result;
12607     }
12608
12609     private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
12610             long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12611         if (r.errorReportReceiver == null) {
12612             return null;
12613         }
12614
12615         if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
12616             return null;
12617         }
12618
12619         ApplicationErrorReport report = new ApplicationErrorReport();
12620         report.packageName = r.info.packageName;
12621         report.installerPackageName = r.errorReportReceiver.getPackageName();
12622         report.processName = r.processName;
12623         report.time = timeMillis;
12624         report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
12625
12626         if (r.crashing || r.forceCrashReport) {
12627             report.type = ApplicationErrorReport.TYPE_CRASH;
12628             report.crashInfo = crashInfo;
12629         } else if (r.notResponding) {
12630             report.type = ApplicationErrorReport.TYPE_ANR;
12631             report.anrInfo = new ApplicationErrorReport.AnrInfo();
12632
12633             report.anrInfo.activity = r.notRespondingReport.tag;
12634             report.anrInfo.cause = r.notRespondingReport.shortMsg;
12635             report.anrInfo.info = r.notRespondingReport.longMsg;
12636         }
12637
12638         return report;
12639     }
12640
12641     public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
12642         enforceNotIsolatedCaller("getProcessesInErrorState");
12643         // assume our apps are happy - lazy create the list
12644         List<ActivityManager.ProcessErrorStateInfo> errList = null;
12645
12646         final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12647                 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12648         int userId = UserHandle.getUserId(Binder.getCallingUid());
12649
12650         synchronized (this) {
12651
12652             // iterate across all processes
12653             for (int i=mLruProcesses.size()-1; i>=0; i--) {
12654                 ProcessRecord app = mLruProcesses.get(i);
12655                 if (!allUsers && app.userId != userId) {
12656                     continue;
12657                 }
12658                 if ((app.thread != null) && (app.crashing || app.notResponding)) {
12659                     // This one's in trouble, so we'll generate a report for it
12660                     // crashes are higher priority (in case there's a crash *and* an anr)
12661                     ActivityManager.ProcessErrorStateInfo report = null;
12662                     if (app.crashing) {
12663                         report = app.crashingReport;
12664                     } else if (app.notResponding) {
12665                         report = app.notRespondingReport;
12666                     }
12667
12668                     if (report != null) {
12669                         if (errList == null) {
12670                             errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
12671                         }
12672                         errList.add(report);
12673                     } else {
12674                         Slog.w(TAG, "Missing app error report, app = " + app.processName +
12675                                 " crashing = " + app.crashing +
12676                                 " notResponding = " + app.notResponding);
12677                     }
12678                 }
12679             }
12680         }
12681
12682         return errList;
12683     }
12684
12685     static int procStateToImportance(int procState, int memAdj,
12686             ActivityManager.RunningAppProcessInfo currApp) {
12687         int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
12688         if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
12689             currApp.lru = memAdj;
12690         } else {
12691             currApp.lru = 0;
12692         }
12693         return imp;
12694     }
12695
12696     private void fillInProcMemInfo(ProcessRecord app,
12697             ActivityManager.RunningAppProcessInfo outInfo) {
12698         outInfo.pid = app.pid;
12699         outInfo.uid = app.info.uid;
12700         if (mHeavyWeightProcess == app) {
12701             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
12702         }
12703         if (app.persistent) {
12704             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
12705         }
12706         if (app.activities.size() > 0) {
12707             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
12708         }
12709         outInfo.lastTrimLevel = app.trimMemoryLevel;
12710         int adj = app.curAdj;
12711         int procState = app.curProcState;
12712         outInfo.importance = procStateToImportance(procState, adj, outInfo);
12713         outInfo.importanceReasonCode = app.adjTypeCode;
12714         outInfo.processState = app.curProcState;
12715     }
12716
12717     public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
12718         enforceNotIsolatedCaller("getRunningAppProcesses");
12719
12720         final int callingUid = Binder.getCallingUid();
12721
12722         // Lazy instantiation of list
12723         List<ActivityManager.RunningAppProcessInfo> runList = null;
12724         final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12725                 callingUid) == PackageManager.PERMISSION_GRANTED;
12726         final int userId = UserHandle.getUserId(callingUid);
12727         final boolean allUids = isGetTasksAllowed(
12728                 "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
12729
12730         synchronized (this) {
12731             // Iterate across all processes
12732             for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
12733                 ProcessRecord app = mLruProcesses.get(i);
12734                 if ((!allUsers && app.userId != userId)
12735                         || (!allUids && app.uid != callingUid)) {
12736                     continue;
12737                 }
12738                 if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
12739                     // Generate process state info for running application
12740                     ActivityManager.RunningAppProcessInfo currApp =
12741                         new ActivityManager.RunningAppProcessInfo(app.processName,
12742                                 app.pid, app.getPackageList());
12743                     fillInProcMemInfo(app, currApp);
12744                     if (app.adjSource instanceof ProcessRecord) {
12745                         currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
12746                         currApp.importanceReasonImportance =
12747                                 ActivityManager.RunningAppProcessInfo.procStateToImportance(
12748                                         app.adjSourceProcState);
12749                     } else if (app.adjSource instanceof ActivityRecord) {
12750                         ActivityRecord r = (ActivityRecord)app.adjSource;
12751                         if (r.app != null) currApp.importanceReasonPid = r.app.pid;
12752                     }
12753                     if (app.adjTarget instanceof ComponentName) {
12754                         currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
12755                     }
12756                     //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
12757                     //        + " lru=" + currApp.lru);
12758                     if (runList == null) {
12759                         runList = new ArrayList<>();
12760                     }
12761                     runList.add(currApp);
12762                 }
12763             }
12764         }
12765         return runList;
12766     }
12767
12768     public List<ApplicationInfo> getRunningExternalApplications() {
12769         enforceNotIsolatedCaller("getRunningExternalApplications");
12770         List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
12771         List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
12772         if (runningApps != null && runningApps.size() > 0) {
12773             Set<String> extList = new HashSet<String>();
12774             for (ActivityManager.RunningAppProcessInfo app : runningApps) {
12775                 if (app.pkgList != null) {
12776                     for (String pkg : app.pkgList) {
12777                         extList.add(pkg);
12778                     }
12779                 }
12780             }
12781             IPackageManager pm = AppGlobals.getPackageManager();
12782             for (String pkg : extList) {
12783                 try {
12784                     ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
12785                     if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
12786                         retList.add(info);
12787                     }
12788                 } catch (RemoteException e) {
12789                 }
12790             }
12791         }
12792         return retList;
12793     }
12794
12795     @Override
12796     public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
12797         enforceNotIsolatedCaller("getMyMemoryState");
12798         synchronized (this) {
12799             ProcessRecord proc;
12800             synchronized (mPidsSelfLocked) {
12801                 proc = mPidsSelfLocked.get(Binder.getCallingPid());
12802             }
12803             fillInProcMemInfo(proc, outInfo);
12804         }
12805     }
12806
12807     @Override
12808     protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
12809         if (checkCallingPermission(android.Manifest.permission.DUMP)
12810                 != PackageManager.PERMISSION_GRANTED) {
12811             pw.println("Permission Denial: can't dump ActivityManager from from pid="
12812                     + Binder.getCallingPid()
12813                     + ", uid=" + Binder.getCallingUid()
12814                     + " without permission "
12815                     + android.Manifest.permission.DUMP);
12816             return;
12817         }
12818
12819         boolean dumpAll = false;
12820         boolean dumpClient = false;
12821         String dumpPackage = null;
12822
12823         int opti = 0;
12824         while (opti < args.length) {
12825             String opt = args[opti];
12826             if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12827                 break;
12828             }
12829             opti++;
12830             if ("-a".equals(opt)) {
12831                 dumpAll = true;
12832             } else if ("-c".equals(opt)) {
12833                 dumpClient = true;
12834             } else if ("-p".equals(opt)) {
12835                 if (opti < args.length) {
12836                     dumpPackage = args[opti];
12837                     opti++;
12838                 } else {
12839                     pw.println("Error: -p option requires package argument");
12840                     return;
12841                 }
12842                 dumpClient = true;
12843             } else if ("-h".equals(opt)) {
12844                 pw.println("Activity manager dump options:");
12845                 pw.println("  [-a] [-c] [-p package] [-h] [cmd] ...");
12846                 pw.println("  cmd may be one of:");
12847                 pw.println("    a[ctivities]: activity stack state");
12848                 pw.println("    r[recents]: recent activities state");
12849                 pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
12850                 pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
12851                 pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
12852                 pw.println("    o[om]: out of memory management");
12853                 pw.println("    perm[issions]: URI permission grant state");
12854                 pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
12855                 pw.println("    provider [COMP_SPEC]: provider client-side state");
12856                 pw.println("    s[ervices] [COMP_SPEC ...]: service state");
12857                 pw.println("    as[sociations]: tracked app associations");
12858                 pw.println("    service [COMP_SPEC]: service client-side state");
12859                 pw.println("    package [PACKAGE_NAME]: all state related to given package");
12860                 pw.println("    all: dump all activities");
12861                 pw.println("    top: dump the top activity");
12862                 pw.println("    write: write all pending state to storage");
12863                 pw.println("    track-associations: enable association tracking");
12864                 pw.println("    untrack-associations: disable and clear association tracking");
12865                 pw.println("  cmd may also be a COMP_SPEC to dump activities.");
12866                 pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
12867                 pw.println("    a partial substring in a component name, a");
12868                 pw.println("    hex object identifier.");
12869                 pw.println("  -a: include all available server state.");
12870                 pw.println("  -c: include client state.");
12871                 pw.println("  -p: limit output to given package.");
12872                 return;
12873             } else {
12874                 pw.println("Unknown argument: " + opt + "; use -h for help");
12875             }
12876         }
12877
12878         long origId = Binder.clearCallingIdentity();
12879         boolean more = false;
12880         // Is the caller requesting to dump a particular piece of data?
12881         if (opti < args.length) {
12882             String cmd = args[opti];
12883             opti++;
12884             if ("activities".equals(cmd) || "a".equals(cmd)) {
12885                 synchronized (this) {
12886                     dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
12887                 }
12888             } else if ("recents".equals(cmd) || "r".equals(cmd)) {
12889                 synchronized (this) {
12890                     dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
12891                 }
12892             } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
12893                 String[] newArgs;
12894                 String name;
12895                 if (opti >= args.length) {
12896                     name = null;
12897                     newArgs = EMPTY_STRING_ARRAY;
12898                 } else {
12899                     dumpPackage = args[opti];
12900                     opti++;
12901                     newArgs = new String[args.length - opti];
12902                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12903                             args.length - opti);
12904                 }
12905                 synchronized (this) {
12906                     dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
12907                 }
12908             } else if ("intents".equals(cmd) || "i".equals(cmd)) {
12909                 String[] newArgs;
12910                 String name;
12911                 if (opti >= args.length) {
12912                     name = null;
12913                     newArgs = EMPTY_STRING_ARRAY;
12914                 } else {
12915                     dumpPackage = args[opti];
12916                     opti++;
12917                     newArgs = new String[args.length - opti];
12918                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12919                             args.length - opti);
12920                 }
12921                 synchronized (this) {
12922                     dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
12923                 }
12924             } else if ("processes".equals(cmd) || "p".equals(cmd)) {
12925                 String[] newArgs;
12926                 String name;
12927                 if (opti >= args.length) {
12928                     name = null;
12929                     newArgs = EMPTY_STRING_ARRAY;
12930                 } else {
12931                     dumpPackage = args[opti];
12932                     opti++;
12933                     newArgs = new String[args.length - opti];
12934                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12935                             args.length - opti);
12936                 }
12937                 synchronized (this) {
12938                     dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
12939                 }
12940             } else if ("oom".equals(cmd) || "o".equals(cmd)) {
12941                 synchronized (this) {
12942                     dumpOomLocked(fd, pw, args, opti, true);
12943                 }
12944             } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
12945                 synchronized (this) {
12946                     dumpPermissionsLocked(fd, pw, args, opti, true, null);
12947                 }
12948             } else if ("provider".equals(cmd)) {
12949                 String[] newArgs;
12950                 String name;
12951                 if (opti >= args.length) {
12952                     name = null;
12953                     newArgs = EMPTY_STRING_ARRAY;
12954                 } else {
12955                     name = args[opti];
12956                     opti++;
12957                     newArgs = new String[args.length - opti];
12958                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12959                 }
12960                 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
12961                     pw.println("No providers match: " + name);
12962                     pw.println("Use -h for help.");
12963                 }
12964             } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
12965                 synchronized (this) {
12966                     dumpProvidersLocked(fd, pw, args, opti, true, null);
12967                 }
12968             } else if ("service".equals(cmd)) {
12969                 String[] newArgs;
12970                 String name;
12971                 if (opti >= args.length) {
12972                     name = null;
12973                     newArgs = EMPTY_STRING_ARRAY;
12974                 } else {
12975                     name = args[opti];
12976                     opti++;
12977                     newArgs = new String[args.length - opti];
12978                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12979                             args.length - opti);
12980                 }
12981                 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
12982                     pw.println("No services match: " + name);
12983                     pw.println("Use -h for help.");
12984                 }
12985             } else if ("package".equals(cmd)) {
12986                 String[] newArgs;
12987                 if (opti >= args.length) {
12988                     pw.println("package: no package name specified");
12989                     pw.println("Use -h for help.");
12990                 } else {
12991                     dumpPackage = args[opti];
12992                     opti++;
12993                     newArgs = new String[args.length - opti];
12994                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12995                             args.length - opti);
12996                     args = newArgs;
12997                     opti = 0;
12998                     more = true;
12999                 }
13000             } else if ("associations".equals(cmd) || "as".equals(cmd)) {
13001                 synchronized (this) {
13002                     dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13003                 }
13004             } else if ("services".equals(cmd) || "s".equals(cmd)) {
13005                 synchronized (this) {
13006                     mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13007                 }
13008             } else if ("write".equals(cmd)) {
13009                 mTaskPersister.flush();
13010                 pw.println("All tasks persisted.");
13011                 return;
13012             } else if ("track-associations".equals(cmd)) {
13013                 synchronized (this) {
13014                     if (!mTrackingAssociations) {
13015                         mTrackingAssociations = true;
13016                         pw.println("Association tracking started.");
13017                     } else {
13018                         pw.println("Association tracking already enabled.");
13019                     }
13020                 }
13021                 return;
13022             } else if ("untrack-associations".equals(cmd)) {
13023                 synchronized (this) {
13024                     if (mTrackingAssociations) {
13025                         mTrackingAssociations = false;
13026                         mAssociations.clear();
13027                         pw.println("Association tracking stopped.");
13028                     } else {
13029                         pw.println("Association tracking not running.");
13030                     }
13031                 }
13032                 return;
13033             } else {
13034                 // Dumping a single activity?
13035                 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
13036                     pw.println("Bad activity command, or no activities match: " + cmd);
13037                     pw.println("Use -h for help.");
13038                 }
13039             }
13040             if (!more) {
13041                 Binder.restoreCallingIdentity(origId);
13042                 return;
13043             }
13044         }
13045
13046         // No piece of data specified, dump everything.
13047         synchronized (this) {
13048             dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13049             pw.println();
13050             if (dumpAll) {
13051                 pw.println("-------------------------------------------------------------------------------");
13052             }
13053             dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13054             pw.println();
13055             if (dumpAll) {
13056                 pw.println("-------------------------------------------------------------------------------");
13057             }
13058             dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13059             pw.println();
13060             if (dumpAll) {
13061                 pw.println("-------------------------------------------------------------------------------");
13062             }
13063             dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13064             pw.println();
13065             if (dumpAll) {
13066                 pw.println("-------------------------------------------------------------------------------");
13067             }
13068             mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13069             pw.println();
13070             if (dumpAll) {
13071                 pw.println("-------------------------------------------------------------------------------");
13072             }
13073             dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13074             pw.println();
13075             if (dumpAll) {
13076                 pw.println("-------------------------------------------------------------------------------");
13077             }
13078             dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13079             if (mAssociations.size() > 0) {
13080                 pw.println();
13081                 if (dumpAll) {
13082                     pw.println("-------------------------------------------------------------------------------");
13083                 }
13084                 dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13085             }
13086             pw.println();
13087             if (dumpAll) {
13088                 pw.println("-------------------------------------------------------------------------------");
13089             }
13090             dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13091         }
13092         Binder.restoreCallingIdentity(origId);
13093     }
13094
13095     void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13096             int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
13097         pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
13098
13099         boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
13100                 dumpPackage);
13101         boolean needSep = printedAnything;
13102
13103         boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
13104                 dumpPackage, needSep, "  mFocusedActivity: ");
13105         if (printed) {
13106             printedAnything = true;
13107             needSep = false;
13108         }
13109
13110         if (dumpPackage == null) {
13111             if (needSep) {
13112                 pw.println();
13113             }
13114             needSep = true;
13115             printedAnything = true;
13116             mStackSupervisor.dump(pw, "  ");
13117         }
13118
13119         if (!printedAnything) {
13120             pw.println("  (nothing)");
13121         }
13122     }
13123
13124     void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13125             int opti, boolean dumpAll, String dumpPackage) {
13126         pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
13127
13128         boolean printedAnything = false;
13129
13130         if (mRecentTasks != null && mRecentTasks.size() > 0) {
13131             boolean printedHeader = false;
13132
13133             final int N = mRecentTasks.size();
13134             for (int i=0; i<N; i++) {
13135                 TaskRecord tr = mRecentTasks.get(i);
13136                 if (dumpPackage != null) {
13137                     if (tr.realActivity == null ||
13138                             !dumpPackage.equals(tr.realActivity)) {
13139                         continue;
13140                     }
13141                 }
13142                 if (!printedHeader) {
13143                     pw.println("  Recent tasks:");
13144                     printedHeader = true;
13145                     printedAnything = true;
13146                 }
13147                 pw.print("  * Recent #"); pw.print(i); pw.print(": ");
13148                         pw.println(tr);
13149                 if (dumpAll) {
13150                     mRecentTasks.get(i).dump(pw, "    ");
13151                 }
13152             }
13153         }
13154
13155         if (!printedAnything) {
13156             pw.println("  (nothing)");
13157         }
13158     }
13159
13160     void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13161             int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
13162         pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
13163
13164         int dumpUid = 0;
13165         if (dumpPackage != null) {
13166             IPackageManager pm = AppGlobals.getPackageManager();
13167             try {
13168                 dumpUid = pm.getPackageUid(dumpPackage, 0);
13169             } catch (RemoteException e) {
13170             }
13171         }
13172
13173         boolean printedAnything = false;
13174
13175         final long now = SystemClock.uptimeMillis();
13176
13177         for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
13178             ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
13179                     = mAssociations.valueAt(i1);
13180             for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
13181                 SparseArray<ArrayMap<String, Association>> sourceUids
13182                         = targetComponents.valueAt(i2);
13183                 for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
13184                     ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
13185                     for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
13186                         Association ass = sourceProcesses.valueAt(i4);
13187                         if (dumpPackage != null) {
13188                             if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
13189                                     && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
13190                                 continue;
13191                             }
13192                         }
13193                         printedAnything = true;
13194                         pw.print("  ");
13195                         pw.print(ass.mTargetProcess);
13196                         pw.print("/");
13197                         UserHandle.formatUid(pw, ass.mTargetUid);
13198                         pw.print(" <- ");
13199                         pw.print(ass.mSourceProcess);
13200                         pw.print("/");
13201                         UserHandle.formatUid(pw, ass.mSourceUid);
13202                         pw.println();
13203                         pw.print("    via ");
13204                         pw.print(ass.mTargetComponent.flattenToShortString());
13205                         pw.println();
13206                         pw.print("    ");
13207                         long dur = ass.mTime;
13208                         if (ass.mNesting > 0) {
13209                             dur += now - ass.mStartTime;
13210                         }
13211                         TimeUtils.formatDuration(dur, pw);
13212                         pw.print(" (");
13213                         pw.print(ass.mCount);
13214                         pw.println(" times)");
13215                         if (ass.mNesting > 0) {
13216                             pw.print("    ");
13217                             pw.print(" Currently active: ");
13218                             TimeUtils.formatDuration(now - ass.mStartTime, pw);
13219                             pw.println();
13220                         }
13221                     }
13222                 }
13223             }
13224
13225         }
13226
13227         if (!printedAnything) {
13228             pw.println("  (nothing)");
13229         }
13230     }
13231
13232     void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13233             int opti, boolean dumpAll, String dumpPackage) {
13234         boolean needSep = false;
13235         boolean printedAnything = false;
13236         int numPers = 0;
13237
13238         pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
13239
13240         if (dumpAll) {
13241             final int NP = mProcessNames.getMap().size();
13242             for (int ip=0; ip<NP; ip++) {
13243                 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
13244                 final int NA = procs.size();
13245                 for (int ia=0; ia<NA; ia++) {
13246                     ProcessRecord r = procs.valueAt(ia);
13247                     if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13248                         continue;
13249                     }
13250                     if (!needSep) {
13251                         pw.println("  All known processes:");
13252                         needSep = true;
13253                         printedAnything = true;
13254                     }
13255                     pw.print(r.persistent ? "  *PERS*" : "  *APP*");
13256                         pw.print(" UID "); pw.print(procs.keyAt(ia));
13257                         pw.print(" "); pw.println(r);
13258                     r.dump(pw, "    ");
13259                     if (r.persistent) {
13260                         numPers++;
13261                     }
13262                 }
13263             }
13264         }
13265
13266         if (mIsolatedProcesses.size() > 0) {
13267             boolean printed = false;
13268             for (int i=0; i<mIsolatedProcesses.size(); i++) {
13269                 ProcessRecord r = mIsolatedProcesses.valueAt(i);
13270                 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13271                     continue;
13272                 }
13273                 if (!printed) {
13274                     if (needSep) {
13275                         pw.println();
13276                     }
13277                     pw.println("  Isolated process list (sorted by uid):");
13278                     printedAnything = true;
13279                     printed = true;
13280                     needSep = true;
13281                 }
13282                 pw.println(String.format("%sIsolated #%2d: %s",
13283                         "    ", i, r.toString()));
13284             }
13285         }
13286
13287         if (mActiveUids.size() > 0) {
13288             if (needSep) {
13289                 pw.println();
13290             }
13291             pw.println("  UID states:");
13292             for (int i=0; i<mActiveUids.size(); i++) {
13293                 UidRecord uidRec = mActiveUids.valueAt(i);
13294                 pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
13295                 pw.print(": "); pw.println(uidRec);
13296             }
13297             needSep = true;
13298             printedAnything = true;
13299         }
13300
13301         if (mLruProcesses.size() > 0) {
13302             if (needSep) {
13303                 pw.println();
13304             }
13305             pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
13306                     pw.print(" total, non-act at ");
13307                     pw.print(mLruProcesses.size()-mLruProcessActivityStart);
13308                     pw.print(", non-svc at ");
13309                     pw.print(mLruProcesses.size()-mLruProcessServiceStart);
13310                     pw.println("):");
13311             dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
13312             needSep = true;
13313             printedAnything = true;
13314         }
13315
13316         if (dumpAll || dumpPackage != null) {
13317             synchronized (mPidsSelfLocked) {
13318                 boolean printed = false;
13319                 for (int i=0; i<mPidsSelfLocked.size(); i++) {
13320                     ProcessRecord r = mPidsSelfLocked.valueAt(i);
13321                     if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13322                         continue;
13323                     }
13324                     if (!printed) {
13325                         if (needSep) pw.println();
13326                         needSep = true;
13327                         pw.println("  PID mappings:");
13328                         printed = true;
13329                         printedAnything = true;
13330                     }
13331                     pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
13332                         pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
13333                 }
13334             }
13335         }
13336
13337         if (mForegroundProcesses.size() > 0) {
13338             synchronized (mPidsSelfLocked) {
13339                 boolean printed = false;
13340                 for (int i=0; i<mForegroundProcesses.size(); i++) {
13341                     ProcessRecord r = mPidsSelfLocked.get(
13342                             mForegroundProcesses.valueAt(i).pid);
13343                     if (dumpPackage != null && (r == null
13344                             || !r.pkgList.containsKey(dumpPackage))) {
13345                         continue;
13346                     }
13347                     if (!printed) {
13348                         if (needSep) pw.println();
13349                         needSep = true;
13350                         pw.println("  Foreground Processes:");
13351                         printed = true;
13352                         printedAnything = true;
13353                     }
13354                     pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
13355                             pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
13356                 }
13357             }
13358         }
13359
13360         if (mPersistentStartingProcesses.size() > 0) {
13361             if (needSep) pw.println();
13362             needSep = true;
13363             printedAnything = true;
13364             pw.println("  Persisent processes that are starting:");
13365             dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
13366                     "Starting Norm", "Restarting PERS", dumpPackage);
13367         }
13368
13369         if (mRemovedProcesses.size() > 0) {
13370             if (needSep) pw.println();
13371             needSep = true;
13372             printedAnything = true;
13373             pw.println("  Processes that are being removed:");
13374             dumpProcessList(pw, this, mRemovedProcesses, "    ",
13375                     "Removed Norm", "Removed PERS", dumpPackage);
13376         }
13377
13378         if (mProcessesOnHold.size() > 0) {
13379             if (needSep) pw.println();
13380             needSep = true;
13381             printedAnything = true;
13382             pw.println("  Processes that are on old until the system is ready:");
13383             dumpProcessList(pw, this, mProcessesOnHold, "    ",
13384                     "OnHold Norm", "OnHold PERS", dumpPackage);
13385         }
13386
13387         needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
13388
13389         if (mProcessCrashTimes.getMap().size() > 0) {
13390             boolean printed = false;
13391             long now = SystemClock.uptimeMillis();
13392             final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
13393             final int NP = pmap.size();
13394             for (int ip=0; ip<NP; ip++) {
13395                 String pname = pmap.keyAt(ip);
13396                 SparseArray<Long> uids = pmap.valueAt(ip);
13397                 final int N = uids.size();
13398                 for (int i=0; i<N; i++) {
13399                     int puid = uids.keyAt(i);
13400                     ProcessRecord r = mProcessNames.get(pname, puid);
13401                     if (dumpPackage != null && (r == null
13402                             || !r.pkgList.containsKey(dumpPackage))) {
13403                         continue;
13404                     }
13405                     if (!printed) {
13406                         if (needSep) pw.println();
13407                         needSep = true;
13408                         pw.println("  Time since processes crashed:");
13409                         printed = true;
13410                         printedAnything = true;
13411                     }
13412                     pw.print("    Process "); pw.print(pname);
13413                             pw.print(" uid "); pw.print(puid);
13414                             pw.print(": last crashed ");
13415                             TimeUtils.formatDuration(now-uids.valueAt(i), pw);
13416                             pw.println(" ago");
13417                 }
13418             }
13419         }
13420
13421         if (mBadProcesses.getMap().size() > 0) {
13422             boolean printed = false;
13423             final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
13424             final int NP = pmap.size();
13425             for (int ip=0; ip<NP; ip++) {
13426                 String pname = pmap.keyAt(ip);
13427                 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
13428                 final int N = uids.size();
13429                 for (int i=0; i<N; i++) {
13430                     int puid = uids.keyAt(i);
13431                     ProcessRecord r = mProcessNames.get(pname, puid);
13432                     if (dumpPackage != null && (r == null
13433                             || !r.pkgList.containsKey(dumpPackage))) {
13434                         continue;
13435                     }
13436                     if (!printed) {
13437                         if (needSep) pw.println();
13438                         needSep = true;
13439                         pw.println("  Bad processes:");
13440                         printedAnything = true;
13441                     }
13442                     BadProcessInfo info = uids.valueAt(i);
13443                     pw.print("    Bad process "); pw.print(pname);
13444                             pw.print(" uid "); pw.print(puid);
13445                             pw.print(": crashed at time "); pw.println(info.time);
13446                     if (info.shortMsg != null) {
13447                         pw.print("      Short msg: "); pw.println(info.shortMsg);
13448                     }
13449                     if (info.longMsg != null) {
13450                         pw.print("      Long msg: "); pw.println(info.longMsg);
13451                     }
13452                     if (info.stack != null) {
13453                         pw.println("      Stack:");
13454                         int lastPos = 0;
13455                         for (int pos=0; pos<info.stack.length(); pos++) {
13456                             if (info.stack.charAt(pos) == '\n') {
13457                                 pw.print("        ");
13458                                 pw.write(info.stack, lastPos, pos-lastPos);
13459                                 pw.println();
13460                                 lastPos = pos+1;
13461                             }
13462                         }
13463                         if (lastPos < info.stack.length()) {
13464                             pw.print("        ");
13465                             pw.write(info.stack, lastPos, info.stack.length()-lastPos);
13466                             pw.println();
13467                         }
13468                     }
13469                 }
13470             }
13471         }
13472
13473         if (dumpPackage == null) {
13474             pw.println();
13475             needSep = false;
13476             pw.println("  mStartedUsers:");
13477             for (int i=0; i<mStartedUsers.size(); i++) {
13478                 UserState uss = mStartedUsers.valueAt(i);
13479                 pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
13480                         pw.print(": "); uss.dump("", pw);
13481             }
13482             pw.print("  mStartedUserArray: [");
13483             for (int i=0; i<mStartedUserArray.length; i++) {
13484                 if (i > 0) pw.print(", ");
13485                 pw.print(mStartedUserArray[i]);
13486             }
13487             pw.println("]");
13488             pw.print("  mUserLru: [");
13489             for (int i=0; i<mUserLru.size(); i++) {
13490                 if (i > 0) pw.print(", ");
13491                 pw.print(mUserLru.get(i));
13492             }
13493             pw.println("]");
13494             if (dumpAll) {
13495                 pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
13496             }
13497             synchronized (mUserProfileGroupIdsSelfLocked) {
13498                 if (mUserProfileGroupIdsSelfLocked.size() > 0) {
13499                     pw.println("  mUserProfileGroupIds:");
13500                     for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
13501                         pw.print("    User #");
13502                         pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
13503                         pw.print(" -> profile #");
13504                         pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
13505                     }
13506                 }
13507             }
13508         }
13509         if (mHomeProcess != null && (dumpPackage == null
13510                 || mHomeProcess.pkgList.containsKey(dumpPackage))) {
13511             if (needSep) {
13512                 pw.println();
13513                 needSep = false;
13514             }
13515             pw.println("  mHomeProcess: " + mHomeProcess);
13516         }
13517         if (mPreviousProcess != null && (dumpPackage == null
13518                 || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
13519             if (needSep) {
13520                 pw.println();
13521                 needSep = false;
13522             }
13523             pw.println("  mPreviousProcess: " + mPreviousProcess);
13524         }
13525         if (dumpAll) {
13526             StringBuilder sb = new StringBuilder(128);
13527             sb.append("  mPreviousProcessVisibleTime: ");
13528             TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
13529             pw.println(sb);
13530         }
13531         if (mHeavyWeightProcess != null && (dumpPackage == null
13532                 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
13533             if (needSep) {
13534                 pw.println();
13535                 needSep = false;
13536             }
13537             pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
13538         }
13539         if (dumpPackage == null) {
13540             pw.println("  mConfiguration: " + mConfiguration);
13541         }
13542         if (dumpAll) {
13543             pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
13544             if (mCompatModePackages.getPackages().size() > 0) {
13545                 boolean printed = false;
13546                 for (Map.Entry<String, Integer> entry
13547                         : mCompatModePackages.getPackages().entrySet()) {
13548                     String pkg = entry.getKey();
13549                     int mode = entry.getValue();
13550                     if (dumpPackage != null && !dumpPackage.equals(pkg)) {
13551                         continue;
13552                     }
13553                     if (!printed) {
13554                         pw.println("  mScreenCompatPackages:");
13555                         printed = true;
13556                     }
13557                     pw.print("    "); pw.print(pkg); pw.print(": ");
13558                             pw.print(mode); pw.println();
13559                 }
13560             }
13561         }
13562         if (dumpPackage == null) {
13563             pw.println("  mWakefulness="
13564                     + PowerManagerInternal.wakefulnessToString(mWakefulness));
13565             pw.println("  mSleepTokens=" + mSleepTokens);
13566             pw.println("  mSleeping=" + mSleeping + " mLockScreenShown="
13567                     + lockScreenShownToString());
13568             pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
13569             if (mRunningVoice != null) {
13570                 pw.println("  mRunningVoice=" + mRunningVoice);
13571                 pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
13572             }
13573         }
13574         if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
13575                 || mOrigWaitForDebugger) {
13576             if (dumpPackage == null || dumpPackage.equals(mDebugApp)
13577                     || dumpPackage.equals(mOrigDebugApp)) {
13578                 if (needSep) {
13579                     pw.println();
13580                     needSep = false;
13581                 }
13582                 pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
13583                         + " mDebugTransient=" + mDebugTransient
13584                         + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
13585             }
13586         }
13587         if (mCurAppTimeTracker != null) {
13588             mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
13589         }
13590         if (mMemWatchProcesses.getMap().size() > 0) {
13591             pw.println("  Mem watch processes:");
13592             final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
13593                     = mMemWatchProcesses.getMap();
13594             for (int i=0; i<procs.size(); i++) {
13595                 final String proc = procs.keyAt(i);
13596                 final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
13597                 for (int j=0; j<uids.size(); j++) {
13598                     if (needSep) {
13599                         pw.println();
13600                         needSep = false;
13601                     }
13602                     StringBuilder sb = new StringBuilder();
13603                     sb.append("    ").append(proc).append('/');
13604                     UserHandle.formatUid(sb, uids.keyAt(j));
13605                     Pair<Long, String> val = uids.valueAt(j);
13606                     sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
13607                     if (val.second != null) {
13608                         sb.append(", report to ").append(val.second);
13609                     }
13610                     pw.println(sb.toString());
13611                 }
13612             }
13613             pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
13614             pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
13615             pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
13616                     pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
13617         }
13618         if (mOpenGlTraceApp != null) {
13619             if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
13620                 if (needSep) {
13621                     pw.println();
13622                     needSep = false;
13623                 }
13624                 pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
13625             }
13626         }
13627         if (mProfileApp != null || mProfileProc != null || mProfileFile != null
13628                 || mProfileFd != null) {
13629             if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
13630                 if (needSep) {
13631                     pw.println();
13632                     needSep = false;
13633                 }
13634                 pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
13635                 pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
13636                 pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
13637                         + mAutoStopProfiler);
13638                 pw.println("  mProfileType=" + mProfileType);
13639             }
13640         }
13641         if (dumpPackage == null) {
13642             if (mAlwaysFinishActivities || mController != null) {
13643                 pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
13644                         + " mController=" + mController);
13645             }
13646             if (dumpAll) {
13647                 pw.println("  Total persistent processes: " + numPers);
13648                 pw.println("  mProcessesReady=" + mProcessesReady
13649                         + " mSystemReady=" + mSystemReady
13650                         + " mBooted=" + mBooted
13651                         + " mFactoryTest=" + mFactoryTest);
13652                 pw.println("  mBooting=" + mBooting
13653                         + " mCallFinishBooting=" + mCallFinishBooting
13654                         + " mBootAnimationComplete=" + mBootAnimationComplete);
13655                 pw.print("  mLastPowerCheckRealtime=");
13656                         TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
13657                         pw.println("");
13658                 pw.print("  mLastPowerCheckUptime=");
13659                         TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
13660                         pw.println("");
13661                 pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
13662                 pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
13663                 pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
13664                 pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
13665                         + " (" + mLruProcesses.size() + " total)"
13666                         + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
13667                         + " mNumServiceProcs=" + mNumServiceProcs
13668                         + " mNewNumServiceProcs=" + mNewNumServiceProcs);
13669                 pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
13670                         + " mLastMemoryLevel" + mLastMemoryLevel
13671                         + " mLastNumProcesses" + mLastNumProcesses);
13672                 long now = SystemClock.uptimeMillis();
13673                 pw.print("  mLastIdleTime=");
13674                         TimeUtils.formatDuration(now, mLastIdleTime, pw);
13675                         pw.print(" mLowRamSinceLastIdle=");
13676                         TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
13677                         pw.println();
13678             }
13679         }
13680
13681         if (!printedAnything) {
13682             pw.println("  (nothing)");
13683         }
13684     }
13685
13686     boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
13687             int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
13688         if (mProcessesToGc.size() > 0) {
13689             boolean printed = false;
13690             long now = SystemClock.uptimeMillis();
13691             for (int i=0; i<mProcessesToGc.size(); i++) {
13692                 ProcessRecord proc = mProcessesToGc.get(i);
13693                 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
13694                     continue;
13695                 }
13696                 if (!printed) {
13697                     if (needSep) pw.println();
13698                     needSep = true;
13699                     pw.println("  Processes that are waiting to GC:");
13700                     printed = true;
13701                 }
13702                 pw.print("    Process "); pw.println(proc);
13703                 pw.print("      lowMem="); pw.print(proc.reportLowMemory);
13704                         pw.print(", last gced=");
13705                         pw.print(now-proc.lastRequestedGc);
13706                         pw.print(" ms ago, last lowMem=");
13707                         pw.print(now-proc.lastLowMemory);
13708                         pw.println(" ms ago");
13709
13710             }
13711         }
13712         return needSep;
13713     }
13714
13715     void printOomLevel(PrintWriter pw, String name, int adj) {
13716         pw.print("    ");
13717         if (adj >= 0) {
13718             pw.print(' ');
13719             if (adj < 10) pw.print(' ');
13720         } else {
13721             if (adj > -10) pw.print(' ');
13722         }
13723         pw.print(adj);
13724         pw.print(": ");
13725         pw.print(name);
13726         pw.print(" (");
13727         pw.print(mProcessList.getMemLevel(adj)/1024);
13728         pw.println(" kB)");
13729     }
13730
13731     boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13732             int opti, boolean dumpAll) {
13733         boolean needSep = false;
13734
13735         if (mLruProcesses.size() > 0) {
13736             if (needSep) pw.println();
13737             needSep = true;
13738             pw.println("  OOM levels:");
13739             printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
13740             printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
13741             printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
13742             printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
13743             printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
13744             printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
13745             printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
13746             printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
13747             printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
13748             printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
13749             printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
13750             printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
13751             printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
13752             printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
13753
13754             if (needSep) pw.println();
13755             pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
13756                     pw.print(" total, non-act at ");
13757                     pw.print(mLruProcesses.size()-mLruProcessActivityStart);
13758                     pw.print(", non-svc at ");
13759                     pw.print(mLruProcesses.size()-mLruProcessServiceStart);
13760                     pw.println("):");
13761             dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
13762             needSep = true;
13763         }
13764
13765         dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
13766
13767         pw.println();
13768         pw.println("  mHomeProcess: " + mHomeProcess);
13769         pw.println("  mPreviousProcess: " + mPreviousProcess);
13770         if (mHeavyWeightProcess != null) {
13771             pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
13772         }
13773
13774         return true;
13775     }
13776
13777     /**
13778      * There are three ways to call this:
13779      *  - no provider specified: dump all the providers
13780      *  - a flattened component name that matched an existing provider was specified as the
13781      *    first arg: dump that one provider
13782      *  - the first arg isn't the flattened component name of an existing provider:
13783      *    dump all providers whose component contains the first arg as a substring
13784      */
13785     protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13786             int opti, boolean dumpAll) {
13787         return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
13788     }
13789
13790     static class ItemMatcher {
13791         ArrayList<ComponentName> components;
13792         ArrayList<String> strings;
13793         ArrayList<Integer> objects;
13794         boolean all;
13795
13796         ItemMatcher() {
13797             all = true;
13798         }
13799
13800         void build(String name) {
13801             ComponentName componentName = ComponentName.unflattenFromString(name);
13802             if (componentName != null) {
13803                 if (components == null) {
13804                     components = new ArrayList<ComponentName>();
13805                 }
13806                 components.add(componentName);
13807                 all = false;
13808             } else {
13809                 int objectId = 0;
13810                 // Not a '/' separated full component name; maybe an object ID?
13811                 try {
13812                     objectId = Integer.parseInt(name, 16);
13813                     if (objects == null) {
13814                         objects = new ArrayList<Integer>();
13815                     }
13816                     objects.add(objectId);
13817                     all = false;
13818                 } catch (RuntimeException e) {
13819                     // Not an integer; just do string match.
13820                     if (strings == null) {
13821                         strings = new ArrayList<String>();
13822                     }
13823                     strings.add(name);
13824                     all = false;
13825                 }
13826             }
13827         }
13828
13829         int build(String[] args, int opti) {
13830             for (; opti<args.length; opti++) {
13831                 String name = args[opti];
13832                 if ("--".equals(name)) {
13833                     return opti+1;
13834                 }
13835                 build(name);
13836             }
13837             return opti;
13838         }
13839
13840         boolean match(Object object, ComponentName comp) {
13841             if (all) {
13842                 return true;
13843             }
13844             if (components != null) {
13845                 for (int i=0; i<components.size(); i++) {
13846                     if (components.get(i).equals(comp)) {
13847                         return true;
13848                     }
13849                 }
13850             }
13851             if (objects != null) {
13852                 for (int i=0; i<objects.size(); i++) {
13853                     if (System.identityHashCode(object) == objects.get(i)) {
13854                         return true;
13855                     }
13856                 }
13857             }
13858             if (strings != null) {
13859                 String flat = comp.flattenToString();
13860                 for (int i=0; i<strings.size(); i++) {
13861                     if (flat.contains(strings.get(i))) {
13862                         return true;
13863                     }
13864                 }
13865             }
13866             return false;
13867         }
13868     }
13869
13870     /**
13871      * There are three things that cmd can be:
13872      *  - a flattened component name that matches an existing activity
13873      *  - the cmd arg isn't the flattened component name of an existing activity:
13874      *    dump all activity whose component contains the cmd as a substring
13875      *  - A hex number of the ActivityRecord object instance.
13876      */
13877     protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13878             int opti, boolean dumpAll) {
13879         ArrayList<ActivityRecord> activities;
13880
13881         synchronized (this) {
13882             activities = mStackSupervisor.getDumpActivitiesLocked(name);
13883         }
13884
13885         if (activities.size() <= 0) {
13886             return false;
13887         }
13888
13889         String[] newArgs = new String[args.length - opti];
13890         System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13891
13892         TaskRecord lastTask = null;
13893         boolean needSep = false;
13894         for (int i=activities.size()-1; i>=0; i--) {
13895             ActivityRecord r = activities.get(i);
13896             if (needSep) {
13897                 pw.println();
13898             }
13899             needSep = true;
13900             synchronized (this) {
13901                 if (lastTask != r.task) {
13902                     lastTask = r.task;
13903                     pw.print("TASK "); pw.print(lastTask.affinity);
13904                             pw.print(" id="); pw.println(lastTask.taskId);
13905                     if (dumpAll) {
13906                         lastTask.dump(pw, "  ");
13907                     }
13908                 }
13909             }
13910             dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
13911         }
13912         return true;
13913     }
13914
13915     /**
13916      * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
13917      * there is a thread associated with the activity.
13918      */
13919     private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
13920             final ActivityRecord r, String[] args, boolean dumpAll) {
13921         String innerPrefix = prefix + "  ";
13922         synchronized (this) {
13923             pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
13924                     pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
13925                     pw.print(" pid=");
13926                     if (r.app != null) pw.println(r.app.pid);
13927                     else pw.println("(not running)");
13928             if (dumpAll) {
13929                 r.dump(pw, innerPrefix);
13930             }
13931         }
13932         if (r.app != null && r.app.thread != null) {
13933             // flush anything that is already in the PrintWriter since the thread is going
13934             // to write to the file descriptor directly
13935             pw.flush();
13936             try {
13937                 TransferPipe tp = new TransferPipe();
13938                 try {
13939                     r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
13940                             r.appToken, innerPrefix, args);
13941                     tp.go(fd);
13942                 } finally {
13943                     tp.kill();
13944                 }
13945             } catch (IOException e) {
13946                 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
13947             } catch (RemoteException e) {
13948                 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
13949             }
13950         }
13951     }
13952
13953     void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13954             int opti, boolean dumpAll, String dumpPackage) {
13955         boolean needSep = false;
13956         boolean onlyHistory = false;
13957         boolean printedAnything = false;
13958
13959         if ("history".equals(dumpPackage)) {
13960             if (opti < args.length && "-s".equals(args[opti])) {
13961                 dumpAll = false;
13962             }
13963             onlyHistory = true;
13964             dumpPackage = null;
13965         }
13966
13967         pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
13968         if (!onlyHistory && dumpAll) {
13969             if (mRegisteredReceivers.size() > 0) {
13970                 boolean printed = false;
13971                 Iterator it = mRegisteredReceivers.values().iterator();
13972                 while (it.hasNext()) {
13973                     ReceiverList r = (ReceiverList)it.next();
13974                     if (dumpPackage != null && (r.app == null ||
13975                             !dumpPackage.equals(r.app.info.packageName))) {
13976                         continue;
13977                     }
13978                     if (!printed) {
13979                         pw.println("  Registered Receivers:");
13980                         needSep = true;
13981                         printed = true;
13982                         printedAnything = true;
13983                     }
13984                     pw.print("  * "); pw.println(r);
13985                     r.dump(pw, "    ");
13986                 }
13987             }
13988
13989             if (mReceiverResolver.dump(pw, needSep ?
13990                     "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
13991                     "    ", dumpPackage, false, false)) {
13992                 needSep = true;
13993                 printedAnything = true;
13994             }
13995         }
13996
13997         for (BroadcastQueue q : mBroadcastQueues) {
13998             needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
13999             printedAnything |= needSep;
14000         }
14001
14002         needSep = true;
14003
14004         if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
14005             for (int user=0; user<mStickyBroadcasts.size(); user++) {
14006                 if (needSep) {
14007                     pw.println();
14008                 }
14009                 needSep = true;
14010                 printedAnything = true;
14011                 pw.print("  Sticky broadcasts for user ");
14012                         pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
14013                 StringBuilder sb = new StringBuilder(128);
14014                 for (Map.Entry<String, ArrayList<Intent>> ent
14015                         : mStickyBroadcasts.valueAt(user).entrySet()) {
14016                     pw.print("  * Sticky action "); pw.print(ent.getKey());
14017                     if (dumpAll) {
14018                         pw.println(":");
14019                         ArrayList<Intent> intents = ent.getValue();
14020                         final int N = intents.size();
14021                         for (int i=0; i<N; i++) {
14022                             sb.setLength(0);
14023                             sb.append("    Intent: ");
14024                             intents.get(i).toShortString(sb, false, true, false, false);
14025                             pw.println(sb.toString());
14026                             Bundle bundle = intents.get(i).getExtras();
14027                             if (bundle != null) {
14028                                 pw.print("      ");
14029                                 pw.println(bundle.toString());
14030                             }
14031                         }
14032                     } else {
14033                         pw.println("");
14034                     }
14035                 }
14036             }
14037         }
14038
14039         if (!onlyHistory && dumpAll) {
14040             pw.println();
14041             for (BroadcastQueue queue : mBroadcastQueues) {
14042                 pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
14043                         + queue.mBroadcastsScheduled);
14044             }
14045             pw.println("  mHandler:");
14046             mHandler.dump(new PrintWriterPrinter(pw), "    ");
14047             needSep = true;
14048             printedAnything = true;
14049         }
14050
14051         if (!printedAnything) {
14052             pw.println("  (nothing)");
14053         }
14054     }
14055
14056     void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14057             int opti, boolean dumpAll, String dumpPackage) {
14058         boolean needSep;
14059         boolean printedAnything = false;
14060
14061         ItemMatcher matcher = new ItemMatcher();
14062         matcher.build(args, opti);
14063
14064         pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
14065
14066         needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
14067         printedAnything |= needSep;
14068
14069         if (mLaunchingProviders.size() > 0) {
14070             boolean printed = false;
14071             for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
14072                 ContentProviderRecord r = mLaunchingProviders.get(i);
14073                 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
14074                     continue;
14075                 }
14076                 if (!printed) {
14077                     if (needSep) pw.println();
14078                     needSep = true;
14079                     pw.println("  Launching content providers:");
14080                     printed = true;
14081                     printedAnything = true;
14082                 }
14083                 pw.print("  Launching #"); pw.print(i); pw.print(": ");
14084                         pw.println(r);
14085             }
14086         }
14087
14088         if (!printedAnything) {
14089             pw.println("  (nothing)");
14090         }
14091     }
14092
14093     void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14094             int opti, boolean dumpAll, String dumpPackage) {
14095         boolean needSep = false;
14096         boolean printedAnything = false;
14097
14098         pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
14099
14100         if (mGrantedUriPermissions.size() > 0) {
14101             boolean printed = false;
14102             int dumpUid = -2;
14103             if (dumpPackage != null) {
14104                 try {
14105                     dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
14106                 } catch (NameNotFoundException e) {
14107                     dumpUid = -1;
14108                 }
14109             }
14110             for (int i=0; i<mGrantedUriPermissions.size(); i++) {
14111                 int uid = mGrantedUriPermissions.keyAt(i);
14112                 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
14113                     continue;
14114                 }
14115                 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
14116                 if (!printed) {
14117                     if (needSep) pw.println();
14118                     needSep = true;
14119                     pw.println("  Granted Uri Permissions:");
14120                     printed = true;
14121                     printedAnything = true;
14122                 }
14123                 pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
14124                 for (UriPermission perm : perms.values()) {
14125                     pw.print("    "); pw.println(perm);
14126                     if (dumpAll) {
14127                         perm.dump(pw, "      ");
14128                     }
14129                 }
14130             }
14131         }
14132
14133         if (!printedAnything) {
14134             pw.println("  (nothing)");
14135         }
14136     }
14137
14138     void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14139             int opti, boolean dumpAll, String dumpPackage) {
14140         boolean printed = false;
14141
14142         pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
14143
14144         if (mIntentSenderRecords.size() > 0) {
14145             Iterator<WeakReference<PendingIntentRecord>> it
14146                     = mIntentSenderRecords.values().iterator();
14147             while (it.hasNext()) {
14148                 WeakReference<PendingIntentRecord> ref = it.next();
14149                 PendingIntentRecord rec = ref != null ? ref.get(): null;
14150                 if (dumpPackage != null && (rec == null
14151                         || !dumpPackage.equals(rec.key.packageName))) {
14152                     continue;
14153                 }
14154                 printed = true;
14155                 if (rec != null) {
14156                     pw.print("  * "); pw.println(rec);
14157                     if (dumpAll) {
14158                         rec.dump(pw, "    ");
14159                     }
14160                 } else {
14161                     pw.print("  * "); pw.println(ref);
14162                 }
14163             }
14164         }
14165
14166         if (!printed) {
14167             pw.println("  (nothing)");
14168         }
14169     }
14170
14171     private static final int dumpProcessList(PrintWriter pw,
14172             ActivityManagerService service, List list,
14173             String prefix, String normalLabel, String persistentLabel,
14174             String dumpPackage) {
14175         int numPers = 0;
14176         final int N = list.size()-1;
14177         for (int i=N; i>=0; i--) {
14178             ProcessRecord r = (ProcessRecord)list.get(i);
14179             if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
14180                 continue;
14181             }
14182             pw.println(String.format("%s%s #%2d: %s",
14183                     prefix, (r.persistent ? persistentLabel : normalLabel),
14184                     i, r.toString()));
14185             if (r.persistent) {
14186                 numPers++;
14187             }
14188         }
14189         return numPers;
14190     }
14191
14192     private static final boolean dumpProcessOomList(PrintWriter pw,
14193             ActivityManagerService service, List<ProcessRecord> origList,
14194             String prefix, String normalLabel, String persistentLabel,
14195             boolean inclDetails, String dumpPackage) {
14196
14197         ArrayList<Pair<ProcessRecord, Integer>> list
14198                 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
14199         for (int i=0; i<origList.size(); i++) {
14200             ProcessRecord r = origList.get(i);
14201             if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14202                 continue;
14203             }
14204             list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
14205         }
14206
14207         if (list.size() <= 0) {
14208             return false;
14209         }
14210
14211         Comparator<Pair<ProcessRecord, Integer>> comparator
14212                 = new Comparator<Pair<ProcessRecord, Integer>>() {
14213             @Override
14214             public int compare(Pair<ProcessRecord, Integer> object1,
14215                     Pair<ProcessRecord, Integer> object2) {
14216                 if (object1.first.setAdj != object2.first.setAdj) {
14217                     return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
14218                 }
14219                 if (object1.second.intValue() != object2.second.intValue()) {
14220                     return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
14221                 }
14222                 return 0;
14223             }
14224         };
14225
14226         Collections.sort(list, comparator);
14227
14228         final long curRealtime = SystemClock.elapsedRealtime();
14229         final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
14230         final long curUptime = SystemClock.uptimeMillis();
14231         final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
14232
14233         for (int i=list.size()-1; i>=0; i--) {
14234             ProcessRecord r = list.get(i).first;
14235             String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
14236             char schedGroup;
14237             switch (r.setSchedGroup) {
14238                 case Process.THREAD_GROUP_BG_NONINTERACTIVE:
14239                     schedGroup = 'B';
14240                     break;
14241                 case Process.THREAD_GROUP_DEFAULT:
14242                     schedGroup = 'F';
14243                     break;
14244                 default:
14245                     schedGroup = '?';
14246                     break;
14247             }
14248             char foreground;
14249             if (r.foregroundActivities) {
14250                 foreground = 'A';
14251             } else if (r.foregroundServices) {
14252                 foreground = 'S';
14253             } else {
14254                 foreground = ' ';
14255             }
14256             String procState = ProcessList.makeProcStateString(r.curProcState);
14257             pw.print(prefix);
14258             pw.print(r.persistent ? persistentLabel : normalLabel);
14259             pw.print(" #");
14260             int num = (origList.size()-1)-list.get(i).second;
14261             if (num < 10) pw.print(' ');
14262             pw.print(num);
14263             pw.print(": ");
14264             pw.print(oomAdj);
14265             pw.print(' ');
14266             pw.print(schedGroup);
14267             pw.print('/');
14268             pw.print(foreground);
14269             pw.print('/');
14270             pw.print(procState);
14271             pw.print(" trm:");
14272             if (r.trimMemoryLevel < 10) pw.print(' ');
14273             pw.print(r.trimMemoryLevel);
14274             pw.print(' ');
14275             pw.print(r.toShortString());
14276             pw.print(" (");
14277             pw.print(r.adjType);
14278             pw.println(')');
14279             if (r.adjSource != null || r.adjTarget != null) {
14280                 pw.print(prefix);
14281                 pw.print("    ");
14282                 if (r.adjTarget instanceof ComponentName) {
14283                     pw.print(((ComponentName)r.adjTarget).flattenToShortString());
14284                 } else if (r.adjTarget != null) {
14285                     pw.print(r.adjTarget.toString());
14286                 } else {
14287                     pw.print("{null}");
14288                 }
14289                 pw.print("<=");
14290                 if (r.adjSource instanceof ProcessRecord) {
14291                     pw.print("Proc{");
14292                     pw.print(((ProcessRecord)r.adjSource).toShortString());
14293                     pw.println("}");
14294                 } else if (r.adjSource != null) {
14295                     pw.println(r.adjSource.toString());
14296                 } else {
14297                     pw.println("{null}");
14298                 }
14299             }
14300             if (inclDetails) {
14301                 pw.print(prefix);
14302                 pw.print("    ");
14303                 pw.print("oom: max="); pw.print(r.maxAdj);
14304                 pw.print(" curRaw="); pw.print(r.curRawAdj);
14305                 pw.print(" setRaw="); pw.print(r.setRawAdj);
14306                 pw.print(" cur="); pw.print(r.curAdj);
14307                 pw.print(" set="); pw.println(r.setAdj);
14308                 pw.print(prefix);
14309                 pw.print("    ");
14310                 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
14311                 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
14312                 pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
14313                 pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
14314                 pw.println();
14315                 pw.print(prefix);
14316                 pw.print("    ");
14317                 pw.print("cached="); pw.print(r.cached);
14318                 pw.print(" empty="); pw.print(r.empty);
14319                 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
14320
14321                 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
14322                     if (r.lastWakeTime != 0) {
14323                         long wtime;
14324                         BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
14325                         synchronized (stats) {
14326                             wtime = stats.getProcessWakeTime(r.info.uid,
14327                                     r.pid, curRealtime);
14328                         }
14329                         long timeUsed = wtime - r.lastWakeTime;
14330                         pw.print(prefix);
14331                         pw.print("    ");
14332                         pw.print("keep awake over ");
14333                         TimeUtils.formatDuration(realtimeSince, pw);
14334                         pw.print(" used ");
14335                         TimeUtils.formatDuration(timeUsed, pw);
14336                         pw.print(" (");
14337                         pw.print((timeUsed*100)/realtimeSince);
14338                         pw.println("%)");
14339                     }
14340                     if (r.lastCpuTime != 0) {
14341                         long timeUsed = r.curCpuTime - r.lastCpuTime;
14342                         pw.print(prefix);
14343                         pw.print("    ");
14344                         pw.print("run cpu over ");
14345                         TimeUtils.formatDuration(uptimeSince, pw);
14346                         pw.print(" used ");
14347                         TimeUtils.formatDuration(timeUsed, pw);
14348                         pw.print(" (");
14349                         pw.print((timeUsed*100)/uptimeSince);
14350                         pw.println("%)");
14351                     }
14352                 }
14353             }
14354         }
14355         return true;
14356     }
14357
14358     ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
14359             String[] args) {
14360         ArrayList<ProcessRecord> procs;
14361         synchronized (this) {
14362             if (args != null && args.length > start
14363                     && args[start].charAt(0) != '-') {
14364                 procs = new ArrayList<ProcessRecord>();
14365                 int pid = -1;
14366                 try {
14367                     pid = Integer.parseInt(args[start]);
14368                 } catch (NumberFormatException e) {
14369                 }
14370                 for (int i=mLruProcesses.size()-1; i>=0; i--) {
14371                     ProcessRecord proc = mLruProcesses.get(i);
14372                     if (proc.pid == pid) {
14373                         procs.add(proc);
14374                     } else if (allPkgs && proc.pkgList != null
14375                             && proc.pkgList.containsKey(args[start])) {
14376                         procs.add(proc);
14377                     } else if (proc.processName.equals(args[start])) {
14378                         procs.add(proc);
14379                     }
14380                 }
14381                 if (procs.size() <= 0) {
14382                     return null;
14383                 }
14384             } else {
14385                 procs = new ArrayList<ProcessRecord>(mLruProcesses);
14386             }
14387         }
14388         return procs;
14389     }
14390
14391     final void dumpGraphicsHardwareUsage(FileDescriptor fd,
14392             PrintWriter pw, String[] args) {
14393         ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
14394         if (procs == null) {
14395             pw.println("No process found for: " + args[0]);
14396             return;
14397         }
14398
14399         long uptime = SystemClock.uptimeMillis();
14400         long realtime = SystemClock.elapsedRealtime();
14401         pw.println("Applications Graphics Acceleration Info:");
14402         pw.println("Uptime: " + uptime + " Realtime: " + realtime);
14403
14404         for (int i = procs.size() - 1 ; i >= 0 ; i--) {
14405             ProcessRecord r = procs.get(i);
14406             if (r.thread != null) {
14407                 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
14408                 pw.flush();
14409                 try {
14410                     TransferPipe tp = new TransferPipe();
14411                     try {
14412                         r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
14413                         tp.go(fd);
14414                     } finally {
14415                         tp.kill();
14416                     }
14417                 } catch (IOException e) {
14418                     pw.println("Failure while dumping the app: " + r);
14419                     pw.flush();
14420                 } catch (RemoteException e) {
14421                     pw.println("Got a RemoteException while dumping the app " + r);
14422                     pw.flush();
14423                 }
14424             }
14425         }
14426     }
14427
14428     final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
14429         ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
14430         if (procs == null) {
14431             pw.println("No process found for: " + args[0]);
14432             return;
14433         }
14434
14435         pw.println("Applications Database Info:");
14436
14437         for (int i = procs.size() - 1 ; i >= 0 ; i--) {
14438             ProcessRecord r = procs.get(i);
14439             if (r.thread != null) {
14440                 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
14441                 pw.flush();
14442                 try {
14443                     TransferPipe tp = new TransferPipe();
14444                     try {
14445                         r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
14446                         tp.go(fd);
14447                     } finally {
14448                         tp.kill();
14449                     }
14450                 } catch (IOException e) {
14451                     pw.println("Failure while dumping the app: " + r);
14452                     pw.flush();
14453                 } catch (RemoteException e) {
14454                     pw.println("Got a RemoteException while dumping the app " + r);
14455                     pw.flush();
14456                 }
14457             }
14458         }
14459     }
14460
14461     final static class MemItem {
14462         final boolean isProc;
14463         final String label;
14464         final String shortLabel;
14465         final long pss;
14466         final int id;
14467         final boolean hasActivities;
14468         ArrayList<MemItem> subitems;
14469
14470         public MemItem(String _label, String _shortLabel, long _pss, int _id,
14471                 boolean _hasActivities) {
14472             isProc = true;
14473             label = _label;
14474             shortLabel = _shortLabel;
14475             pss = _pss;
14476             id = _id;
14477             hasActivities = _hasActivities;
14478         }
14479
14480         public MemItem(String _label, String _shortLabel, long _pss, int _id) {
14481             isProc = false;
14482             label = _label;
14483             shortLabel = _shortLabel;
14484             pss = _pss;
14485             id = _id;
14486             hasActivities = false;
14487         }
14488     }
14489
14490     static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
14491             ArrayList<MemItem> items, boolean sort, boolean isCompact) {
14492         if (sort && !isCompact) {
14493             Collections.sort(items, new Comparator<MemItem>() {
14494                 @Override
14495                 public int compare(MemItem lhs, MemItem rhs) {
14496                     if (lhs.pss < rhs.pss) {
14497                         return 1;
14498                     } else if (lhs.pss > rhs.pss) {
14499                         return -1;
14500                     }
14501                     return 0;
14502                 }
14503             });
14504         }
14505
14506         for (int i=0; i<items.size(); i++) {
14507             MemItem mi = items.get(i);
14508             if (!isCompact) {
14509                 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
14510             } else if (mi.isProc) {
14511                 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
14512                 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
14513                 pw.println(mi.hasActivities ? ",a" : ",e");
14514             } else {
14515                 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
14516                 pw.println(mi.pss);
14517             }
14518             if (mi.subitems != null) {
14519                 dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
14520                         true, isCompact);
14521             }
14522         }
14523     }
14524
14525     // These are in KB.
14526     static final long[] DUMP_MEM_BUCKETS = new long[] {
14527         5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
14528         120*1024, 160*1024, 200*1024,
14529         250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
14530         1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
14531     };
14532
14533     static final void appendMemBucket(StringBuilder out, long memKB, String label,
14534             boolean stackLike) {
14535         int start = label.lastIndexOf('.');
14536         if (start >= 0) start++;
14537         else start = 0;
14538         int end = label.length();
14539         for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
14540             if (DUMP_MEM_BUCKETS[i] >= memKB) {
14541                 long bucket = DUMP_MEM_BUCKETS[i]/1024;
14542                 out.append(bucket);
14543                 out.append(stackLike ? "MB." : "MB ");
14544                 out.append(label, start, end);
14545                 return;
14546             }
14547         }
14548         out.append(memKB/1024);
14549         out.append(stackLike ? "MB." : "MB ");
14550         out.append(label, start, end);
14551     }
14552
14553     static final int[] DUMP_MEM_OOM_ADJ = new int[] {
14554             ProcessList.NATIVE_ADJ,
14555             ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
14556             ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
14557             ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
14558             ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
14559             ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
14560             ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
14561     };
14562     static final String[] DUMP_MEM_OOM_LABEL = new String[] {
14563             "Native",
14564             "System", "Persistent", "Persistent Service", "Foreground",
14565             "Visible", "Perceptible",
14566             "Heavy Weight", "Backup",
14567             "A Services", "Home",
14568             "Previous", "B Services", "Cached"
14569     };
14570     static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
14571             "native",
14572             "sys", "pers", "persvc", "fore",
14573             "vis", "percept",
14574             "heavy", "backup",
14575             "servicea", "home",
14576             "prev", "serviceb", "cached"
14577     };
14578
14579     private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
14580             long realtime, boolean isCheckinRequest, boolean isCompact) {
14581         if (isCheckinRequest || isCompact) {
14582             // short checkin version
14583             pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
14584         } else {
14585             pw.println("Applications Memory Usage (kB):");
14586             pw.println("Uptime: " + uptime + " Realtime: " + realtime);
14587         }
14588     }
14589
14590     private static final int KSM_SHARED = 0;
14591     private static final int KSM_SHARING = 1;
14592     private static final int KSM_UNSHARED = 2;
14593     private static final int KSM_VOLATILE = 3;
14594
14595     private final long[] getKsmInfo() {
14596         long[] longOut = new long[4];
14597         final int[] SINGLE_LONG_FORMAT = new int[] {
14598             Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
14599         };
14600         long[] longTmp = new long[1];
14601         Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
14602                 SINGLE_LONG_FORMAT, null, longTmp, null);
14603         longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14604         longTmp[0] = 0;
14605         Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
14606                 SINGLE_LONG_FORMAT, null, longTmp, null);
14607         longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14608         longTmp[0] = 0;
14609         Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
14610                 SINGLE_LONG_FORMAT, null, longTmp, null);
14611         longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14612         longTmp[0] = 0;
14613         Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
14614                 SINGLE_LONG_FORMAT, null, longTmp, null);
14615         longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14616         return longOut;
14617     }
14618
14619     final void dumpApplicationMemoryUsage(FileDescriptor fd,
14620             PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
14621         boolean dumpDetails = false;
14622         boolean dumpFullDetails = false;
14623         boolean dumpDalvik = false;
14624         boolean dumpSummaryOnly = false;
14625         boolean oomOnly = false;
14626         boolean isCompact = false;
14627         boolean localOnly = false;
14628         boolean packages = false;
14629
14630         int opti = 0;
14631         while (opti < args.length) {
14632             String opt = args[opti];
14633             if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
14634                 break;
14635             }
14636             opti++;
14637             if ("-a".equals(opt)) {
14638                 dumpDetails = true;
14639                 dumpFullDetails = true;
14640                 dumpDalvik = true;
14641             } else if ("-d".equals(opt)) {
14642                 dumpDalvik = true;
14643             } else if ("-c".equals(opt)) {
14644                 isCompact = true;
14645             } else if ("-s".equals(opt)) {
14646                 dumpDetails = true;
14647                 dumpSummaryOnly = true;
14648             } else if ("--oom".equals(opt)) {
14649                 oomOnly = true;
14650             } else if ("--local".equals(opt)) {
14651                 localOnly = true;
14652             } else if ("--package".equals(opt)) {
14653                 packages = true;
14654             } else if ("-h".equals(opt)) {
14655                 pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
14656                 pw.println("  -a: include all available information for each process.");
14657                 pw.println("  -d: include dalvik details.");
14658                 pw.println("  -c: dump in a compact machine-parseable representation.");
14659                 pw.println("  -s: dump only summary of application memory usage.");
14660                 pw.println("  --oom: only show processes organized by oom adj.");
14661                 pw.println("  --local: only collect details locally, don't call process.");
14662                 pw.println("  --package: interpret process arg as package, dumping all");
14663                 pw.println("             processes that have loaded that package.");
14664                 pw.println("If [process] is specified it can be the name or ");
14665                 pw.println("pid of a specific process to dump.");
14666                 return;
14667             } else {
14668                 pw.println("Unknown argument: " + opt + "; use -h for help");
14669             }
14670         }
14671
14672         final boolean isCheckinRequest = scanArgs(args, "--checkin");
14673         long uptime = SystemClock.uptimeMillis();
14674         long realtime = SystemClock.elapsedRealtime();
14675         final long[] tmpLong = new long[1];
14676
14677         ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
14678         if (procs == null) {
14679             // No Java processes.  Maybe they want to print a native process.
14680             if (args != null && args.length > opti
14681                     && args[opti].charAt(0) != '-') {
14682                 ArrayList<ProcessCpuTracker.Stats> nativeProcs
14683                         = new ArrayList<ProcessCpuTracker.Stats>();
14684                 updateCpuStatsNow();
14685                 int findPid = -1;
14686                 try {
14687                     findPid = Integer.parseInt(args[opti]);
14688                 } catch (NumberFormatException e) {
14689                 }
14690                 synchronized (mProcessCpuTracker) {
14691                     final int N = mProcessCpuTracker.countStats();
14692                     for (int i=0; i<N; i++) {
14693                         ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14694                         if (st.pid == findPid || (st.baseName != null
14695                                 && st.baseName.equals(args[opti]))) {
14696                             nativeProcs.add(st);
14697                         }
14698                     }
14699                 }
14700                 if (nativeProcs.size() > 0) {
14701                     dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
14702                             isCompact);
14703                     Debug.MemoryInfo mi = null;
14704                     for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
14705                         final ProcessCpuTracker.Stats r = nativeProcs.get(i);
14706                         final int pid = r.pid;
14707                         if (!isCheckinRequest && dumpDetails) {
14708                             pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
14709                         }
14710                         if (mi == null) {
14711                             mi = new Debug.MemoryInfo();
14712                         }
14713                         if (dumpDetails || (!brief && !oomOnly)) {
14714                             Debug.getMemoryInfo(pid, mi);
14715                         } else {
14716                             mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
14717                             mi.dalvikPrivateDirty = (int)tmpLong[0];
14718                         }
14719                         ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
14720                                 dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
14721                         if (isCheckinRequest) {
14722                             pw.println();
14723                         }
14724                     }
14725                     return;
14726                 }
14727             }
14728             pw.println("No process found for: " + args[opti]);
14729             return;
14730         }
14731
14732         if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
14733             dumpDetails = true;
14734         }
14735
14736         dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
14737
14738         String[] innerArgs = new String[args.length-opti];
14739         System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
14740
14741         ArrayList<MemItem> procMems = new ArrayList<MemItem>();
14742         final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
14743         long nativePss = 0;
14744         long dalvikPss = 0;
14745         long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
14746                 EmptyArray.LONG;
14747         long otherPss = 0;
14748         long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
14749
14750         long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
14751         ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
14752                 new ArrayList[DUMP_MEM_OOM_LABEL.length];
14753
14754         long totalPss = 0;
14755         long cachedPss = 0;
14756
14757         Debug.MemoryInfo mi = null;
14758         for (int i = procs.size() - 1 ; i >= 0 ; i--) {
14759             final ProcessRecord r = procs.get(i);
14760             final IApplicationThread thread;
14761             final int pid;
14762             final int oomAdj;
14763             final boolean hasActivities;
14764             synchronized (this) {
14765                 thread = r.thread;
14766                 pid = r.pid;
14767                 oomAdj = r.getSetAdjWithServices();
14768                 hasActivities = r.activities.size() > 0;
14769             }
14770             if (thread != null) {
14771                 if (!isCheckinRequest && dumpDetails) {
14772                     pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
14773                 }
14774                 if (mi == null) {
14775                     mi = new Debug.MemoryInfo();
14776                 }
14777                 if (dumpDetails || (!brief && !oomOnly)) {
14778                     Debug.getMemoryInfo(pid, mi);
14779                 } else {
14780                     mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
14781                     mi.dalvikPrivateDirty = (int)tmpLong[0];
14782                 }
14783                 if (dumpDetails) {
14784                     if (localOnly) {
14785                         ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
14786                                 dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
14787                         if (isCheckinRequest) {
14788                             pw.println();
14789                         }
14790                     } else {
14791                         try {
14792                             pw.flush();
14793                             thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
14794                                     dumpDalvik, dumpSummaryOnly, innerArgs);
14795                         } catch (RemoteException e) {
14796                             if (!isCheckinRequest) {
14797                                 pw.println("Got RemoteException!");
14798                                 pw.flush();
14799                             }
14800                         }
14801                     }
14802                 }
14803
14804                 final long myTotalPss = mi.getTotalPss();
14805                 final long myTotalUss = mi.getTotalUss();
14806
14807                 synchronized (this) {
14808                     if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
14809                         // Record this for posterity if the process has been stable.
14810                         r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
14811                     }
14812                 }
14813
14814                 if (!isCheckinRequest && mi != null) {
14815                     totalPss += myTotalPss;
14816                     MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
14817                             (hasActivities ? " / activities)" : ")"),
14818                             r.processName, myTotalPss, pid, hasActivities);
14819                     procMems.add(pssItem);
14820                     procMemsMap.put(pid, pssItem);
14821
14822                     nativePss += mi.nativePss;
14823                     dalvikPss += mi.dalvikPss;
14824                     for (int j=0; j<dalvikSubitemPss.length; j++) {
14825                         dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
14826                     }
14827                     otherPss += mi.otherPss;
14828                     for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14829                         long mem = mi.getOtherPss(j);
14830                         miscPss[j] += mem;
14831                         otherPss -= mem;
14832                     }
14833
14834                     if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
14835                         cachedPss += myTotalPss;
14836                     }
14837
14838                     for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
14839                         if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
14840                                 || oomIndex == (oomPss.length-1)) {
14841                             oomPss[oomIndex] += myTotalPss;
14842                             if (oomProcs[oomIndex] == null) {
14843                                 oomProcs[oomIndex] = new ArrayList<MemItem>();
14844                             }
14845                             oomProcs[oomIndex].add(pssItem);
14846                             break;
14847                         }
14848                     }
14849                 }
14850             }
14851         }
14852
14853         long nativeProcTotalPss = 0;
14854
14855         if (!isCheckinRequest && procs.size() > 1 && !packages) {
14856             // If we are showing aggregations, also look for native processes to
14857             // include so that our aggregations are more accurate.
14858             updateCpuStatsNow();
14859             mi = null;
14860             synchronized (mProcessCpuTracker) {
14861                 final int N = mProcessCpuTracker.countStats();
14862                 for (int i=0; i<N; i++) {
14863                     ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14864                     if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
14865                         if (mi == null) {
14866                             mi = new Debug.MemoryInfo();
14867                         }
14868                         if (!brief && !oomOnly) {
14869                             Debug.getMemoryInfo(st.pid, mi);
14870                         } else {
14871                             mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
14872                             mi.nativePrivateDirty = (int)tmpLong[0];
14873                         }
14874
14875                         final long myTotalPss = mi.getTotalPss();
14876                         totalPss += myTotalPss;
14877                         nativeProcTotalPss += myTotalPss;
14878
14879                         MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
14880                                 st.name, myTotalPss, st.pid, false);
14881                         procMems.add(pssItem);
14882
14883                         nativePss += mi.nativePss;
14884                         dalvikPss += mi.dalvikPss;
14885                         for (int j=0; j<dalvikSubitemPss.length; j++) {
14886                             dalvikSubitemPss[j] += mi.getOtherPss(
14887                                     Debug.MemoryInfo.NUM_OTHER_STATS + j);
14888                         }
14889                         otherPss += mi.otherPss;
14890                         for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14891                             long mem = mi.getOtherPss(j);
14892                             miscPss[j] += mem;
14893                             otherPss -= mem;
14894                         }
14895                         oomPss[0] += myTotalPss;
14896                         if (oomProcs[0] == null) {
14897                             oomProcs[0] = new ArrayList<MemItem>();
14898                         }
14899                         oomProcs[0].add(pssItem);
14900                     }
14901                 }
14902             }
14903
14904             ArrayList<MemItem> catMems = new ArrayList<MemItem>();
14905
14906             catMems.add(new MemItem("Native", "Native", nativePss, -1));
14907             final MemItem dalvikItem = new MemItem("Dalvik", "Dalvik", dalvikPss, -2);
14908             if (dalvikSubitemPss.length > 0) {
14909                 dalvikItem.subitems = new ArrayList<MemItem>();
14910                 for (int j=0; j<dalvikSubitemPss.length; j++) {
14911                     final String name = Debug.MemoryInfo.getOtherLabel(
14912                             Debug.MemoryInfo.NUM_OTHER_STATS + j);
14913                     dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j], j));
14914                 }
14915             }
14916             catMems.add(dalvikItem);
14917             catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
14918             for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14919                 String label = Debug.MemoryInfo.getOtherLabel(j);
14920                 catMems.add(new MemItem(label, label, miscPss[j], j));
14921             }
14922
14923             ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
14924             for (int j=0; j<oomPss.length; j++) {
14925                 if (oomPss[j] != 0) {
14926                     String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
14927                             : DUMP_MEM_OOM_LABEL[j];
14928                     MemItem item = new MemItem(label, label, oomPss[j],
14929                             DUMP_MEM_OOM_ADJ[j]);
14930                     item.subitems = oomProcs[j];
14931                     oomMems.add(item);
14932                 }
14933             }
14934
14935             if (!brief && !oomOnly && !isCompact) {
14936                 pw.println();
14937                 pw.println("Total PSS by process:");
14938                 dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
14939                 pw.println();
14940             }
14941             if (!isCompact) {
14942                 pw.println("Total PSS by OOM adjustment:");
14943             }
14944             dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
14945             if (!brief && !oomOnly) {
14946                 PrintWriter out = categoryPw != null ? categoryPw : pw;
14947                 if (!isCompact) {
14948                     out.println();
14949                     out.println("Total PSS by category:");
14950                 }
14951                 dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
14952             }
14953             if (!isCompact) {
14954                 pw.println();
14955             }
14956             MemInfoReader memInfo = new MemInfoReader();
14957             memInfo.readMemInfo();
14958             if (nativeProcTotalPss > 0) {
14959                 synchronized (this) {
14960                     final long cachedKb = memInfo.getCachedSizeKb();
14961                     final long freeKb = memInfo.getFreeSizeKb();
14962                     final long zramKb = memInfo.getZramTotalSizeKb();
14963                     final long kernelKb = memInfo.getKernelUsedSizeKb();
14964                     EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
14965                             kernelKb*1024, nativeProcTotalPss*1024);
14966                     mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
14967                             nativeProcTotalPss);
14968                 }
14969             }
14970             if (!brief) {
14971                 if (!isCompact) {
14972                     pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
14973                     pw.print(" kB (status ");
14974                     switch (mLastMemoryLevel) {
14975                         case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
14976                             pw.println("normal)");
14977                             break;
14978                         case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
14979                             pw.println("moderate)");
14980                             break;
14981                         case ProcessStats.ADJ_MEM_FACTOR_LOW:
14982                             pw.println("low)");
14983                             break;
14984                         case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
14985                             pw.println("critical)");
14986                             break;
14987                         default:
14988                             pw.print(mLastMemoryLevel);
14989                             pw.println(")");
14990                             break;
14991                     }
14992                     pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
14993                             + memInfo.getFreeSizeKb()); pw.print(" kB (");
14994                             pw.print(cachedPss); pw.print(" cached pss + ");
14995                             pw.print(memInfo.getCachedSizeKb()); pw.print(" cached kernel + ");
14996                             pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
14997                 } else {
14998                     pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
14999                     pw.print(cachedPss + memInfo.getCachedSizeKb()
15000                             + memInfo.getFreeSizeKb()); pw.print(",");
15001                     pw.println(totalPss - cachedPss);
15002                 }
15003             }
15004             if (!isCompact) {
15005                 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
15006                         + memInfo.getKernelUsedSizeKb()); pw.print(" kB (");
15007                         pw.print(totalPss - cachedPss); pw.print(" used pss + ");
15008                         pw.print(memInfo.getKernelUsedSizeKb()); pw.print(" kernel)\n");
15009                 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
15010                         - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
15011                         - memInfo.getKernelUsedSizeKb()); pw.println(" kB");
15012             }
15013             if (!brief) {
15014                 if (memInfo.getZramTotalSizeKb() != 0) {
15015                     if (!isCompact) {
15016                         pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
15017                                 pw.print(" kB physical used for ");
15018                                 pw.print(memInfo.getSwapTotalSizeKb()
15019                                         - memInfo.getSwapFreeSizeKb());
15020                                 pw.print(" kB in swap (");
15021                                 pw.print(memInfo.getSwapTotalSizeKb());
15022                                 pw.println(" kB total swap)");
15023                     } else {
15024                         pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
15025                                 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
15026                                 pw.println(memInfo.getSwapFreeSizeKb());
15027                     }
15028                 }
15029                 final long[] ksm = getKsmInfo();
15030                 if (!isCompact) {
15031                     if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
15032                             || ksm[KSM_VOLATILE] != 0) {
15033                         pw.print("      KSM: "); pw.print(ksm[KSM_SHARING]);
15034                                 pw.print(" kB saved from shared ");
15035                                 pw.print(ksm[KSM_SHARED]); pw.println(" kB");
15036                         pw.print("           "); pw.print(ksm[KSM_UNSHARED]);
15037                                 pw.print(" kB unshared; ");
15038                                 pw.print(ksm[KSM_VOLATILE]); pw.println(" kB volatile");
15039                     }
15040                     pw.print("   Tuning: ");
15041                     pw.print(ActivityManager.staticGetMemoryClass());
15042                     pw.print(" (large ");
15043                     pw.print(ActivityManager.staticGetLargeMemoryClass());
15044                     pw.print("), oom ");
15045                     pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
15046                     pw.print(" kB");
15047                     pw.print(", restore limit ");
15048                     pw.print(mProcessList.getCachedRestoreThresholdKb());
15049                     pw.print(" kB");
15050                     if (ActivityManager.isLowRamDeviceStatic()) {
15051                         pw.print(" (low-ram)");
15052                     }
15053                     if (ActivityManager.isHighEndGfx()) {
15054                         pw.print(" (high-end-gfx)");
15055                     }
15056                     pw.println();
15057                 } else {
15058                     pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
15059                     pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
15060                     pw.print(","); pw.println(ksm[KSM_VOLATILE]);
15061                     pw.print("tuning,");
15062                     pw.print(ActivityManager.staticGetMemoryClass());
15063                     pw.print(',');
15064                     pw.print(ActivityManager.staticGetLargeMemoryClass());
15065                     pw.print(',');
15066                     pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
15067                     if (ActivityManager.isLowRamDeviceStatic()) {
15068                         pw.print(",low-ram");
15069                     }
15070                     if (ActivityManager.isHighEndGfx()) {
15071                         pw.print(",high-end-gfx");
15072                     }
15073                     pw.println();
15074                 }
15075             }
15076         }
15077     }
15078
15079     private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
15080             long memtrack, String name) {
15081         sb.append("  ");
15082         sb.append(ProcessList.makeOomAdjString(oomAdj));
15083         sb.append(' ');
15084         sb.append(ProcessList.makeProcStateString(procState));
15085         sb.append(' ');
15086         ProcessList.appendRamKb(sb, pss);
15087         sb.append(" kB: ");
15088         sb.append(name);
15089         if (memtrack > 0) {
15090             sb.append(" (");
15091             sb.append(memtrack);
15092             sb.append(" kB memtrack)");
15093         }
15094     }
15095
15096     private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
15097         appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
15098         sb.append(" (pid ");
15099         sb.append(mi.pid);
15100         sb.append(") ");
15101         sb.append(mi.adjType);
15102         sb.append('\n');
15103         if (mi.adjReason != null) {
15104             sb.append("                      ");
15105             sb.append(mi.adjReason);
15106             sb.append('\n');
15107         }
15108     }
15109
15110     void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
15111         final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
15112         for (int i=0, N=memInfos.size(); i<N; i++) {
15113             ProcessMemInfo mi = memInfos.get(i);
15114             infoMap.put(mi.pid, mi);
15115         }
15116         updateCpuStatsNow();
15117         long[] memtrackTmp = new long[1];
15118         synchronized (mProcessCpuTracker) {
15119             final int N = mProcessCpuTracker.countStats();
15120             for (int i=0; i<N; i++) {
15121                 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15122                 if (st.vsize > 0) {
15123                     long pss = Debug.getPss(st.pid, null, memtrackTmp);
15124                     if (pss > 0) {
15125                         if (infoMap.indexOfKey(st.pid) < 0) {
15126                             ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
15127                                     ProcessList.NATIVE_ADJ, -1, "native", null);
15128                             mi.pss = pss;
15129                             mi.memtrack = memtrackTmp[0];
15130                             memInfos.add(mi);
15131                         }
15132                     }
15133                 }
15134             }
15135         }
15136
15137         long totalPss = 0;
15138         long totalMemtrack = 0;
15139         for (int i=0, N=memInfos.size(); i<N; i++) {
15140             ProcessMemInfo mi = memInfos.get(i);
15141             if (mi.pss == 0) {
15142                 mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
15143                 mi.memtrack = memtrackTmp[0];
15144             }
15145             totalPss += mi.pss;
15146             totalMemtrack += mi.memtrack;
15147         }
15148         Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
15149             @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
15150                 if (lhs.oomAdj != rhs.oomAdj) {
15151                     return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
15152                 }
15153                 if (lhs.pss != rhs.pss) {
15154                     return lhs.pss < rhs.pss ? 1 : -1;
15155                 }
15156                 return 0;
15157             }
15158         });
15159
15160         StringBuilder tag = new StringBuilder(128);
15161         StringBuilder stack = new StringBuilder(128);
15162         tag.append("Low on memory -- ");
15163         appendMemBucket(tag, totalPss, "total", false);
15164         appendMemBucket(stack, totalPss, "total", true);
15165
15166         StringBuilder fullNativeBuilder = new StringBuilder(1024);
15167         StringBuilder shortNativeBuilder = new StringBuilder(1024);
15168         StringBuilder fullJavaBuilder = new StringBuilder(1024);
15169
15170         boolean firstLine = true;
15171         int lastOomAdj = Integer.MIN_VALUE;
15172         long extraNativeRam = 0;
15173         long extraNativeMemtrack = 0;
15174         long cachedPss = 0;
15175         for (int i=0, N=memInfos.size(); i<N; i++) {
15176             ProcessMemInfo mi = memInfos.get(i);
15177
15178             if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
15179                 cachedPss += mi.pss;
15180             }
15181
15182             if (mi.oomAdj != ProcessList.NATIVE_ADJ
15183                     && (mi.oomAdj < ProcessList.SERVICE_ADJ
15184                             || mi.oomAdj == ProcessList.HOME_APP_ADJ
15185                             || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
15186                 if (lastOomAdj != mi.oomAdj) {
15187                     lastOomAdj = mi.oomAdj;
15188                     if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15189                         tag.append(" / ");
15190                     }
15191                     if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
15192                         if (firstLine) {
15193                             stack.append(":");
15194                             firstLine = false;
15195                         }
15196                         stack.append("\n\t at ");
15197                     } else {
15198                         stack.append("$");
15199                     }
15200                 } else {
15201                     tag.append(" ");
15202                     stack.append("$");
15203                 }
15204                 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15205                     appendMemBucket(tag, mi.pss, mi.name, false);
15206                 }
15207                 appendMemBucket(stack, mi.pss, mi.name, true);
15208                 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
15209                         && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
15210                     stack.append("(");
15211                     for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
15212                         if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
15213                             stack.append(DUMP_MEM_OOM_LABEL[k]);
15214                             stack.append(":");
15215                             stack.append(DUMP_MEM_OOM_ADJ[k]);
15216                         }
15217                     }
15218                     stack.append(")");
15219                 }
15220             }
15221
15222             appendMemInfo(fullNativeBuilder, mi);
15223             if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
15224                 // The short form only has native processes that are >= 512K.
15225                 if (mi.pss >= 512) {
15226                     appendMemInfo(shortNativeBuilder, mi);
15227                 } else {
15228                     extraNativeRam += mi.pss;
15229                     extraNativeMemtrack += mi.memtrack;
15230                 }
15231             } else {
15232                 // Short form has all other details, but if we have collected RAM
15233                 // from smaller native processes let's dump a summary of that.
15234                 if (extraNativeRam > 0) {
15235                     appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
15236                             -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
15237                     shortNativeBuilder.append('\n');
15238                     extraNativeRam = 0;
15239                 }
15240                 appendMemInfo(fullJavaBuilder, mi);
15241             }
15242         }
15243
15244         fullJavaBuilder.append("           ");
15245         ProcessList.appendRamKb(fullJavaBuilder, totalPss);
15246         fullJavaBuilder.append(" kB: TOTAL");
15247         if (totalMemtrack > 0) {
15248             fullJavaBuilder.append(" (");
15249             fullJavaBuilder.append(totalMemtrack);
15250             fullJavaBuilder.append(" kB memtrack)");
15251         } else {
15252         }
15253         fullJavaBuilder.append("\n");
15254
15255         MemInfoReader memInfo = new MemInfoReader();
15256         memInfo.readMemInfo();
15257         final long[] infos = memInfo.getRawInfo();
15258
15259         StringBuilder memInfoBuilder = new StringBuilder(1024);
15260         Debug.getMemInfo(infos);
15261         memInfoBuilder.append("  MemInfo: ");
15262         memInfoBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
15263         memInfoBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
15264         memInfoBuilder.append(infos[Debug.MEMINFO_VM_ALLOC_USED]).append(" kB vm alloc, ");
15265         memInfoBuilder.append(infos[Debug.MEMINFO_PAGE_TABLES]).append(" kB page tables ");
15266         memInfoBuilder.append(infos[Debug.MEMINFO_KERNEL_STACK]).append(" kB kernel stack\n");
15267         memInfoBuilder.append("           ");
15268         memInfoBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
15269         memInfoBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
15270         memInfoBuilder.append(infos[Debug.MEMINFO_MAPPED]).append(" kB mapped, ");
15271         memInfoBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
15272         if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
15273             memInfoBuilder.append("  ZRAM: ");
15274             memInfoBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
15275             memInfoBuilder.append(" kB RAM, ");
15276             memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
15277             memInfoBuilder.append(" kB swap total, ");
15278             memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
15279             memInfoBuilder.append(" kB swap free\n");
15280         }
15281         final long[] ksm = getKsmInfo();
15282         if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
15283                 || ksm[KSM_VOLATILE] != 0) {
15284             memInfoBuilder.append("  KSM: "); memInfoBuilder.append(ksm[KSM_SHARING]);
15285             memInfoBuilder.append(" kB saved from shared ");
15286             memInfoBuilder.append(ksm[KSM_SHARED]); memInfoBuilder.append(" kB\n");
15287             memInfoBuilder.append("       "); memInfoBuilder.append(ksm[KSM_UNSHARED]);
15288             memInfoBuilder.append(" kB unshared; ");
15289             memInfoBuilder.append(ksm[KSM_VOLATILE]); memInfoBuilder.append(" kB volatile\n");
15290         }
15291         memInfoBuilder.append("  Free RAM: ");
15292         memInfoBuilder.append(cachedPss + memInfo.getCachedSizeKb()
15293                 + memInfo.getFreeSizeKb());
15294         memInfoBuilder.append(" kB\n");
15295         memInfoBuilder.append("  Used RAM: ");
15296         memInfoBuilder.append(totalPss - cachedPss + memInfo.getKernelUsedSizeKb());
15297         memInfoBuilder.append(" kB\n");
15298         memInfoBuilder.append("  Lost RAM: ");
15299         memInfoBuilder.append(memInfo.getTotalSizeKb()
15300                 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
15301                 - memInfo.getKernelUsedSizeKb());
15302         memInfoBuilder.append(" kB\n");
15303         Slog.i(TAG, "Low on memory:");
15304         Slog.i(TAG, shortNativeBuilder.toString());
15305         Slog.i(TAG, fullJavaBuilder.toString());
15306         Slog.i(TAG, memInfoBuilder.toString());
15307
15308         StringBuilder dropBuilder = new StringBuilder(1024);
15309         /*
15310         StringWriter oomSw = new StringWriter();
15311         PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
15312         StringWriter catSw = new StringWriter();
15313         PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
15314         String[] emptyArgs = new String[] { };
15315         dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
15316         oomPw.flush();
15317         String oomString = oomSw.toString();
15318         */
15319         dropBuilder.append("Low on memory:");
15320         dropBuilder.append(stack);
15321         dropBuilder.append('\n');
15322         dropBuilder.append(fullNativeBuilder);
15323         dropBuilder.append(fullJavaBuilder);
15324         dropBuilder.append('\n');
15325         dropBuilder.append(memInfoBuilder);
15326         dropBuilder.append('\n');
15327         /*
15328         dropBuilder.append(oomString);
15329         dropBuilder.append('\n');
15330         */
15331         StringWriter catSw = new StringWriter();
15332         synchronized (ActivityManagerService.this) {
15333             PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
15334             String[] emptyArgs = new String[] { };
15335             catPw.println();
15336             dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
15337             catPw.println();
15338             mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
15339                     false, false, null);
15340             catPw.println();
15341             dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
15342             catPw.flush();
15343         }
15344         dropBuilder.append(catSw.toString());
15345         addErrorToDropBox("lowmem", null, "system_server", null,
15346                 null, tag.toString(), dropBuilder.toString(), null, null);
15347         //Slog.i(TAG, "Sent to dropbox:");
15348         //Slog.i(TAG, dropBuilder.toString());
15349         synchronized (ActivityManagerService.this) {
15350             long now = SystemClock.uptimeMillis();
15351             if (mLastMemUsageReportTime < now) {
15352                 mLastMemUsageReportTime = now;
15353             }
15354         }
15355     }
15356
15357     /**
15358      * Searches array of arguments for the specified string
15359      * @param args array of argument strings
15360      * @param value value to search for
15361      * @return true if the value is contained in the array
15362      */
15363     private static boolean scanArgs(String[] args, String value) {
15364         if (args != null) {
15365             for (String arg : args) {
15366                 if (value.equals(arg)) {
15367                     return true;
15368                 }
15369             }
15370         }
15371         return false;
15372     }
15373
15374     private final boolean removeDyingProviderLocked(ProcessRecord proc,
15375             ContentProviderRecord cpr, boolean always) {
15376         final boolean inLaunching = mLaunchingProviders.contains(cpr);
15377
15378         if (!inLaunching || always) {
15379             synchronized (cpr) {
15380                 cpr.launchingApp = null;
15381                 cpr.notifyAll();
15382             }
15383             mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
15384             String names[] = cpr.info.authority.split(";");
15385             for (int j = 0; j < names.length; j++) {
15386                 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
15387             }
15388         }
15389
15390         for (int i = cpr.connections.size() - 1; i >= 0; i--) {
15391             ContentProviderConnection conn = cpr.connections.get(i);
15392             if (conn.waiting) {
15393                 // If this connection is waiting for the provider, then we don't
15394                 // need to mess with its process unless we are always removing
15395                 // or for some reason the provider is not currently launching.
15396                 if (inLaunching && !always) {
15397                     continue;
15398                 }
15399             }
15400             ProcessRecord capp = conn.client;
15401             conn.dead = true;
15402             if (conn.stableCount > 0) {
15403                 if (!capp.persistent && capp.thread != null
15404                         && capp.pid != 0
15405                         && capp.pid != MY_PID) {
15406                     capp.kill("depends on provider "
15407                             + cpr.name.flattenToShortString()
15408                             + " in dying proc " + (proc != null ? proc.processName : "??"), true);
15409                 }
15410             } else if (capp.thread != null && conn.provider.provider != null) {
15411                 try {
15412                     capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
15413                 } catch (RemoteException e) {
15414                 }
15415                 // In the protocol here, we don't expect the client to correctly
15416                 // clean up this connection, we'll just remove it.
15417                 cpr.connections.remove(i);
15418                 if (conn.client.conProviders.remove(conn)) {
15419                     stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
15420                 }
15421             }
15422         }
15423
15424         if (inLaunching && always) {
15425             mLaunchingProviders.remove(cpr);
15426         }
15427         return inLaunching;
15428     }
15429
15430     /**
15431      * Main code for cleaning up a process when it has gone away.  This is
15432      * called both as a result of the process dying, or directly when stopping
15433      * a process when running in single process mode.
15434      *
15435      * @return Returns true if the given process has been restarted, so the
15436      * app that was passed in must remain on the process lists.
15437      */
15438     private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
15439             boolean restarting, boolean allowRestart, int index) {
15440         if (index >= 0) {
15441             removeLruProcessLocked(app);
15442             ProcessList.remove(app.pid);
15443         }
15444
15445         mProcessesToGc.remove(app);
15446         mPendingPssProcesses.remove(app);
15447
15448         // Dismiss any open dialogs.
15449         if (app.crashDialog != null && !app.forceCrashReport) {
15450             app.crashDialog.dismiss();
15451             app.crashDialog = null;
15452         }
15453         if (app.anrDialog != null) {
15454             app.anrDialog.dismiss();
15455             app.anrDialog = null;
15456         }
15457         if (app.waitDialog != null) {
15458             app.waitDialog.dismiss();
15459             app.waitDialog = null;
15460         }
15461
15462         app.crashing = false;
15463         app.notResponding = false;
15464
15465         app.resetPackageList(mProcessStats);
15466         app.unlinkDeathRecipient();
15467         app.makeInactive(mProcessStats);
15468         app.waitingToKill = null;
15469         app.forcingToForeground = null;
15470         updateProcessForegroundLocked(app, false, false);
15471         app.foregroundActivities = false;
15472         app.hasShownUi = false;
15473         app.treatLikeActivity = false;
15474         app.hasAboveClient = false;
15475         app.hasClientActivities = false;
15476
15477         mServices.killServicesLocked(app, allowRestart);
15478
15479         boolean restart = false;
15480
15481         // Remove published content providers.
15482         for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
15483             ContentProviderRecord cpr = app.pubProviders.valueAt(i);
15484             final boolean always = app.bad || !allowRestart;
15485             boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
15486             if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
15487                 // We left the provider in the launching list, need to
15488                 // restart it.
15489                 restart = true;
15490             }
15491
15492             cpr.provider = null;
15493             cpr.proc = null;
15494         }
15495         app.pubProviders.clear();
15496
15497         // Take care of any launching providers waiting for this process.
15498         if (checkAppInLaunchingProvidersLocked(app, false)) {
15499             restart = true;
15500         }
15501
15502         // Unregister from connected content providers.
15503         if (!app.conProviders.isEmpty()) {
15504             for (int i = app.conProviders.size() - 1; i >= 0; i--) {
15505                 ContentProviderConnection conn = app.conProviders.get(i);
15506                 conn.provider.connections.remove(conn);
15507                 stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
15508                         conn.provider.name);
15509             }
15510             app.conProviders.clear();
15511         }
15512
15513         // At this point there may be remaining entries in mLaunchingProviders
15514         // where we were the only one waiting, so they are no longer of use.
15515         // Look for these and clean up if found.
15516         // XXX Commented out for now.  Trying to figure out a way to reproduce
15517         // the actual situation to identify what is actually going on.
15518         if (false) {
15519             for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
15520                 ContentProviderRecord cpr = mLaunchingProviders.get(i);
15521                 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
15522                     synchronized (cpr) {
15523                         cpr.launchingApp = null;
15524                         cpr.notifyAll();
15525                     }
15526                 }
15527             }
15528         }
15529
15530         skipCurrentReceiverLocked(app);
15531
15532         // Unregister any receivers.
15533         for (int i = app.receivers.size() - 1; i >= 0; i--) {
15534             removeReceiverLocked(app.receivers.valueAt(i));
15535         }
15536         app.receivers.clear();
15537
15538         // If the app is undergoing backup, tell the backup manager about it
15539         if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
15540             if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
15541                     + mBackupTarget.appInfo + " died during backup");
15542             try {
15543                 IBackupManager bm = IBackupManager.Stub.asInterface(
15544                         ServiceManager.getService(Context.BACKUP_SERVICE));
15545                 bm.agentDisconnected(app.info.packageName);
15546             } catch (RemoteException e) {
15547                 // can't happen; backup manager is local
15548             }
15549         }
15550
15551         for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
15552             ProcessChangeItem item = mPendingProcessChanges.get(i);
15553             if (item.pid == app.pid) {
15554                 mPendingProcessChanges.remove(i);
15555                 mAvailProcessChanges.add(item);
15556             }
15557         }
15558         mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
15559
15560         // If the caller is restarting this app, then leave it in its
15561         // current lists and let the caller take care of it.
15562         if (restarting) {
15563             return false;
15564         }
15565
15566         if (!app.persistent || app.isolated) {
15567             if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
15568                     "Removing non-persistent process during cleanup: " + app);
15569             removeProcessNameLocked(app.processName, app.uid);
15570             if (mHeavyWeightProcess == app) {
15571                 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
15572                         mHeavyWeightProcess.userId, 0));
15573                 mHeavyWeightProcess = null;
15574             }
15575         } else if (!app.removed) {
15576             // This app is persistent, so we need to keep its record around.
15577             // If it is not already on the pending app list, add it there
15578             // and start a new process for it.
15579             if (mPersistentStartingProcesses.indexOf(app) < 0) {
15580                 mPersistentStartingProcesses.add(app);
15581                 restart = true;
15582             }
15583         }
15584         if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
15585                 TAG_CLEANUP, "Clean-up removing on hold: " + app);
15586         mProcessesOnHold.remove(app);
15587
15588         if (app == mHomeProcess) {
15589             mHomeProcess = null;
15590         }
15591         if (app == mPreviousProcess) {
15592             mPreviousProcess = null;
15593         }
15594
15595         if (restart && !app.isolated) {
15596             // We have components that still need to be running in the
15597             // process, so re-launch it.
15598             if (index < 0) {
15599                 ProcessList.remove(app.pid);
15600             }
15601             addProcessNameLocked(app);
15602             startProcessLocked(app, "restart", app.processName);
15603             return true;
15604         } else if (app.pid > 0 && app.pid != MY_PID) {
15605             // Goodbye!
15606             boolean removed;
15607             synchronized (mPidsSelfLocked) {
15608                 mPidsSelfLocked.remove(app.pid);
15609                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
15610             }
15611             mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
15612             if (app.isolated) {
15613                 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
15614             }
15615             app.setPid(0);
15616         }
15617         return false;
15618     }
15619
15620     boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
15621         // Look through the content providers we are waiting to have launched,
15622         // and if any run in this process then either schedule a restart of
15623         // the process or kill the client waiting for it if this process has
15624         // gone bad.
15625         boolean restart = false;
15626         for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
15627             ContentProviderRecord cpr = mLaunchingProviders.get(i);
15628             if (cpr.launchingApp == app) {
15629                 if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
15630                     restart = true;
15631                 } else {
15632                     removeDyingProviderLocked(app, cpr, true);
15633                 }
15634             }
15635         }
15636         return restart;
15637     }
15638
15639     // =========================================================
15640     // SERVICES
15641     // =========================================================
15642
15643     @Override
15644     public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
15645             int flags) {
15646         enforceNotIsolatedCaller("getServices");
15647         synchronized (this) {
15648             return mServices.getRunningServiceInfoLocked(maxNum, flags);
15649         }
15650     }
15651
15652     @Override
15653     public PendingIntent getRunningServiceControlPanel(ComponentName name) {
15654         enforceNotIsolatedCaller("getRunningServiceControlPanel");
15655         synchronized (this) {
15656             return mServices.getRunningServiceControlPanelLocked(name);
15657         }
15658     }
15659
15660     @Override
15661     public ComponentName startService(IApplicationThread caller, Intent service,
15662             String resolvedType, String callingPackage, int userId)
15663             throws TransactionTooLargeException {
15664         enforceNotIsolatedCaller("startService");
15665         // Refuse possible leaked file descriptors
15666         if (service != null && service.hasFileDescriptors() == true) {
15667             throw new IllegalArgumentException("File descriptors passed in Intent");
15668         }
15669
15670         if (callingPackage == null) {
15671             throw new IllegalArgumentException("callingPackage cannot be null");
15672         }
15673
15674         if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
15675                 "startService: " + service + " type=" + resolvedType);
15676         synchronized(this) {
15677             final int callingPid = Binder.getCallingPid();
15678             final int callingUid = Binder.getCallingUid();
15679             final long origId = Binder.clearCallingIdentity();
15680             ComponentName res = mServices.startServiceLocked(caller, service,
15681                     resolvedType, callingPid, callingUid, callingPackage, userId);
15682             Binder.restoreCallingIdentity(origId);
15683             return res;
15684         }
15685     }
15686
15687     ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
15688             String callingPackage, int userId)
15689             throws TransactionTooLargeException {
15690         synchronized(this) {
15691             if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
15692                     "startServiceInPackage: " + service + " type=" + resolvedType);
15693             final long origId = Binder.clearCallingIdentity();
15694             ComponentName res = mServices.startServiceLocked(null, service,
15695                     resolvedType, -1, uid, callingPackage, userId);
15696             Binder.restoreCallingIdentity(origId);
15697             return res;
15698         }
15699     }
15700
15701     @Override
15702     public int stopService(IApplicationThread caller, Intent service,
15703             String resolvedType, int userId) {
15704         enforceNotIsolatedCaller("stopService");
15705         // Refuse possible leaked file descriptors
15706         if (service != null && service.hasFileDescriptors() == true) {
15707             throw new IllegalArgumentException("File descriptors passed in Intent");
15708         }
15709
15710         synchronized(this) {
15711             return mServices.stopServiceLocked(caller, service, resolvedType, userId);
15712         }
15713     }
15714
15715     @Override
15716     public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
15717         enforceNotIsolatedCaller("peekService");
15718         // Refuse possible leaked file descriptors
15719         if (service != null && service.hasFileDescriptors() == true) {
15720             throw new IllegalArgumentException("File descriptors passed in Intent");
15721         }
15722
15723         if (callingPackage == null) {
15724             throw new IllegalArgumentException("callingPackage cannot be null");
15725         }
15726
15727         synchronized(this) {
15728             return mServices.peekServiceLocked(service, resolvedType, callingPackage);
15729         }
15730     }
15731
15732     @Override
15733     public boolean stopServiceToken(ComponentName className, IBinder token,
15734             int startId) {
15735         synchronized(this) {
15736             return mServices.stopServiceTokenLocked(className, token, startId);
15737         }
15738     }
15739
15740     @Override
15741     public void setServiceForeground(ComponentName className, IBinder token,
15742             int id, Notification notification, boolean removeNotification) {
15743         synchronized(this) {
15744             mServices.setServiceForegroundLocked(className, token, id, notification,
15745                     removeNotification);
15746         }
15747     }
15748
15749     @Override
15750     public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
15751             boolean requireFull, String name, String callerPackage) {
15752         return handleIncomingUser(callingPid, callingUid, userId, allowAll,
15753                 requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
15754     }
15755
15756     int unsafeConvertIncomingUser(int userId) {
15757         return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
15758                 ? mCurrentUserId : userId;
15759     }
15760
15761     int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
15762             int allowMode, String name, String callerPackage) {
15763         final int callingUserId = UserHandle.getUserId(callingUid);
15764         if (callingUserId == userId) {
15765             return userId;
15766         }
15767
15768         // Note that we may be accessing mCurrentUserId outside of a lock...
15769         // shouldn't be a big deal, if this is being called outside
15770         // of a locked context there is intrinsically a race with
15771         // the value the caller will receive and someone else changing it.
15772         // We assume that USER_CURRENT_OR_SELF will use the current user; later
15773         // we will switch to the calling user if access to the current user fails.
15774         int targetUserId = unsafeConvertIncomingUser(userId);
15775
15776         if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
15777             final boolean allow;
15778             if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
15779                     callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
15780                 // If the caller has this permission, they always pass go.  And collect $200.
15781                 allow = true;
15782             } else if (allowMode == ALLOW_FULL_ONLY) {
15783                 // We require full access, sucks to be you.
15784                 allow = false;
15785             } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
15786                     callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
15787                 // If the caller does not have either permission, they are always doomed.
15788                 allow = false;
15789             } else if (allowMode == ALLOW_NON_FULL) {
15790                 // We are blanket allowing non-full access, you lucky caller!
15791                 allow = true;
15792             } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
15793                 // We may or may not allow this depending on whether the two users are
15794                 // in the same profile.
15795                 synchronized (mUserProfileGroupIdsSelfLocked) {
15796                     int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
15797                             UserInfo.NO_PROFILE_GROUP_ID);
15798                     int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
15799                             UserInfo.NO_PROFILE_GROUP_ID);
15800                     allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
15801                             && callingProfile == targetProfile;
15802                 }
15803             } else {
15804                 throw new IllegalArgumentException("Unknown mode: " + allowMode);
15805             }
15806             if (!allow) {
15807                 if (userId == UserHandle.USER_CURRENT_OR_SELF) {
15808                     // In this case, they would like to just execute as their
15809                     // owner user instead of failing.
15810                     targetUserId = callingUserId;
15811                 } else {
15812                     StringBuilder builder = new StringBuilder(128);
15813                     builder.append("Permission Denial: ");
15814                     builder.append(name);
15815                     if (callerPackage != null) {
15816                         builder.append(" from ");
15817                         builder.append(callerPackage);
15818                     }
15819                     builder.append(" asks to run as user ");
15820                     builder.append(userId);
15821                     builder.append(" but is calling from user ");
15822                     builder.append(UserHandle.getUserId(callingUid));
15823                     builder.append("; this requires ");
15824                     builder.append(INTERACT_ACROSS_USERS_FULL);
15825                     if (allowMode != ALLOW_FULL_ONLY) {
15826                         builder.append(" or ");
15827                         builder.append(INTERACT_ACROSS_USERS);
15828                     }
15829                     String msg = builder.toString();
15830                     Slog.w(TAG, msg);
15831                     throw new SecurityException(msg);
15832                 }
15833             }
15834         }
15835         if (!allowAll && targetUserId < 0) {
15836             throw new IllegalArgumentException(
15837                     "Call does not support special user #" + targetUserId);
15838         }
15839         // Check shell permission
15840         if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) {
15841             if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES,
15842                     targetUserId)) {
15843                 throw new SecurityException("Shell does not have permission to access user "
15844                         + targetUserId + "\n " + Debug.getCallers(3));
15845             }
15846         }
15847         return targetUserId;
15848     }
15849
15850     boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
15851             String className, int flags) {
15852         boolean result = false;
15853         // For apps that don't have pre-defined UIDs, check for permission
15854         if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
15855             if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
15856                 if (ActivityManager.checkUidPermission(
15857                         INTERACT_ACROSS_USERS,
15858                         aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
15859                     ComponentName comp = new ComponentName(aInfo.packageName, className);
15860                     String msg = "Permission Denial: Component " + comp.flattenToShortString()
15861                             + " requests FLAG_SINGLE_USER, but app does not hold "
15862                             + INTERACT_ACROSS_USERS;
15863                     Slog.w(TAG, msg);
15864                     throw new SecurityException(msg);
15865                 }
15866                 // Permission passed
15867                 result = true;
15868             }
15869         } else if ("system".equals(componentProcessName)) {
15870             result = true;
15871         } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
15872             // Phone app and persistent apps are allowed to export singleuser providers.
15873             result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
15874                     || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
15875         }
15876         if (DEBUG_MU) Slog.v(TAG_MU,
15877                 "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
15878                 + Integer.toHexString(flags) + ") = " + result);
15879         return result;
15880     }
15881
15882     /**
15883      * Checks to see if the caller is in the same app as the singleton
15884      * component, or the component is in a special app. It allows special apps
15885      * to export singleton components but prevents exporting singleton
15886      * components for regular apps.
15887      */
15888     boolean isValidSingletonCall(int callingUid, int componentUid) {
15889         int componentAppId = UserHandle.getAppId(componentUid);
15890         return UserHandle.isSameApp(callingUid, componentUid)
15891                 || componentAppId == Process.SYSTEM_UID
15892                 || componentAppId == Process.PHONE_UID
15893                 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
15894                         == PackageManager.PERMISSION_GRANTED;
15895     }
15896
15897     public int bindService(IApplicationThread caller, IBinder token, Intent service,
15898             String resolvedType, IServiceConnection connection, int flags, String callingPackage,
15899             int userId) throws TransactionTooLargeException {
15900         enforceNotIsolatedCaller("bindService");
15901
15902         // Refuse possible leaked file descriptors
15903         if (service != null && service.hasFileDescriptors() == true) {
15904             throw new IllegalArgumentException("File descriptors passed in Intent");
15905         }
15906
15907         if (callingPackage == null) {
15908             throw new IllegalArgumentException("callingPackage cannot be null");
15909         }
15910
15911         synchronized(this) {
15912             return mServices.bindServiceLocked(caller, token, service,
15913                     resolvedType, connection, flags, callingPackage, userId);
15914         }
15915     }
15916
15917     public boolean unbindService(IServiceConnection connection) {
15918         synchronized (this) {
15919             return mServices.unbindServiceLocked(connection);
15920         }
15921     }
15922
15923     public void publishService(IBinder token, Intent intent, IBinder service) {
15924         // Refuse possible leaked file descriptors
15925         if (intent != null && intent.hasFileDescriptors() == true) {
15926             throw new IllegalArgumentException("File descriptors passed in Intent");
15927         }
15928
15929         synchronized(this) {
15930             if (!(token instanceof ServiceRecord)) {
15931                 throw new IllegalArgumentException("Invalid service token");
15932             }
15933             mServices.publishServiceLocked((ServiceRecord)token, intent, service);
15934         }
15935     }
15936
15937     public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
15938         // Refuse possible leaked file descriptors
15939         if (intent != null && intent.hasFileDescriptors() == true) {
15940             throw new IllegalArgumentException("File descriptors passed in Intent");
15941         }
15942
15943         synchronized(this) {
15944             mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
15945         }
15946     }
15947
15948     public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
15949         synchronized(this) {
15950             if (!(token instanceof ServiceRecord)) {
15951                 Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
15952                 throw new IllegalArgumentException("Invalid service token");
15953             }
15954             mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
15955         }
15956     }
15957
15958     // =========================================================
15959     // BACKUP AND RESTORE
15960     // =========================================================
15961
15962     // Cause the target app to be launched if necessary and its backup agent
15963     // instantiated.  The backup agent will invoke backupAgentCreated() on the
15964     // activity manager to announce its creation.
15965     public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
15966         if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
15967                 "bindBackupAgent: app=" + app + " mode=" + backupMode);
15968         enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
15969
15970         synchronized(this) {
15971             // !!! TODO: currently no check here that we're already bound
15972             BatteryStatsImpl.Uid.Pkg.Serv ss = null;
15973             BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15974             synchronized (stats) {
15975                 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
15976             }
15977
15978             // Backup agent is now in use, its package can't be stopped.
15979             try {
15980                 AppGlobals.getPackageManager().setPackageStoppedState(
15981                         app.packageName, false, UserHandle.getUserId(app.uid));
15982             } catch (RemoteException e) {
15983             } catch (IllegalArgumentException e) {
15984                 Slog.w(TAG, "Failed trying to unstop package "
15985                         + app.packageName + ": " + e);
15986             }
15987
15988             BackupRecord r = new BackupRecord(ss, app, backupMode);
15989             ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
15990                     ? new ComponentName(app.packageName, app.backupAgentName)
15991                     : new ComponentName("android", "FullBackupAgent");
15992             // startProcessLocked() returns existing proc's record if it's already running
15993             ProcessRecord proc = startProcessLocked(app.processName, app,
15994                     false, 0, "backup", hostingName, false, false, false);
15995             if (proc == null) {
15996                 Slog.e(TAG, "Unable to start backup agent process " + r);
15997                 return false;
15998             }
15999
16000             r.app = proc;
16001             mBackupTarget = r;
16002             mBackupAppName = app.packageName;
16003
16004             // Try not to kill the process during backup
16005             updateOomAdjLocked(proc);
16006
16007             // If the process is already attached, schedule the creation of the backup agent now.
16008             // If it is not yet live, this will be done when it attaches to the framework.
16009             if (proc.thread != null) {
16010                 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
16011                 try {
16012                     proc.thread.scheduleCreateBackupAgent(app,
16013                             compatibilityInfoForPackageLocked(app), backupMode);
16014                 } catch (RemoteException e) {
16015                     // Will time out on the backup manager side
16016                 }
16017             } else {
16018                 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
16019             }
16020             // Invariants: at this point, the target app process exists and the application
16021             // is either already running or in the process of coming up.  mBackupTarget and
16022             // mBackupAppName describe the app, so that when it binds back to the AM we
16023             // know that it's scheduled for a backup-agent operation.
16024         }
16025
16026         return true;
16027     }
16028
16029     @Override
16030     public void clearPendingBackup() {
16031         if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
16032         enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
16033
16034         synchronized (this) {
16035             mBackupTarget = null;
16036             mBackupAppName = null;
16037         }
16038     }
16039
16040     // A backup agent has just come up
16041     public void backupAgentCreated(String agentPackageName, IBinder agent) {
16042         if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
16043                 + " = " + agent);
16044
16045         synchronized(this) {
16046             if (!agentPackageName.equals(mBackupAppName)) {
16047                 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
16048                 return;
16049             }
16050         }
16051
16052         long oldIdent = Binder.clearCallingIdentity();
16053         try {
16054             IBackupManager bm = IBackupManager.Stub.asInterface(
16055                     ServiceManager.getService(Context.BACKUP_SERVICE));
16056             bm.agentConnected(agentPackageName, agent);
16057         } catch (RemoteException e) {
16058             // can't happen; the backup manager service is local
16059         } catch (Exception e) {
16060             Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
16061             e.printStackTrace();
16062         } finally {
16063             Binder.restoreCallingIdentity(oldIdent);
16064         }
16065     }
16066
16067     // done with this agent
16068     public void unbindBackupAgent(ApplicationInfo appInfo) {
16069         if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
16070         if (appInfo == null) {
16071             Slog.w(TAG, "unbind backup agent for null app");
16072             return;
16073         }
16074
16075         synchronized(this) {
16076             try {
16077                 if (mBackupAppName == null) {
16078                     Slog.w(TAG, "Unbinding backup agent with no active backup");
16079                     return;
16080                 }
16081
16082                 if (!mBackupAppName.equals(appInfo.packageName)) {
16083                     Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
16084                     return;
16085                 }
16086
16087                 // Not backing this app up any more; reset its OOM adjustment
16088                 final ProcessRecord proc = mBackupTarget.app;
16089                 updateOomAdjLocked(proc);
16090
16091                 // If the app crashed during backup, 'thread' will be null here
16092                 if (proc.thread != null) {
16093                     try {
16094                         proc.thread.scheduleDestroyBackupAgent(appInfo,
16095                                 compatibilityInfoForPackageLocked(appInfo));
16096                     } catch (Exception e) {
16097                         Slog.e(TAG, "Exception when unbinding backup agent:");
16098                         e.printStackTrace();
16099                     }
16100                 }
16101             } finally {
16102                 mBackupTarget = null;
16103                 mBackupAppName = null;
16104             }
16105         }
16106     }
16107     // =========================================================
16108     // BROADCASTS
16109     // =========================================================
16110
16111     boolean isPendingBroadcastProcessLocked(int pid) {
16112         return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
16113                 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
16114     }
16115
16116     void skipPendingBroadcastLocked(int pid) {
16117             Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
16118             for (BroadcastQueue queue : mBroadcastQueues) {
16119                 queue.skipPendingBroadcastLocked(pid);
16120             }
16121     }
16122
16123     // The app just attached; send any pending broadcasts that it should receive
16124     boolean sendPendingBroadcastsLocked(ProcessRecord app) {
16125         boolean didSomething = false;
16126         for (BroadcastQueue queue : mBroadcastQueues) {
16127             didSomething |= queue.sendPendingBroadcastsLocked(app);
16128         }
16129         return didSomething;
16130     }
16131
16132     public Intent registerReceiver(IApplicationThread caller, String callerPackage,
16133             IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
16134         enforceNotIsolatedCaller("registerReceiver");
16135         ArrayList<Intent> stickyIntents = null;
16136         ProcessRecord callerApp = null;
16137         int callingUid;
16138         int callingPid;
16139         synchronized(this) {
16140             if (caller != null) {
16141                 callerApp = getRecordForAppLocked(caller);
16142                 if (callerApp == null) {
16143                     throw new SecurityException(
16144                             "Unable to find app for caller " + caller
16145                             + " (pid=" + Binder.getCallingPid()
16146                             + ") when registering receiver " + receiver);
16147                 }
16148                 if (callerApp.info.uid != Process.SYSTEM_UID &&
16149                         !callerApp.pkgList.containsKey(callerPackage) &&
16150                         !"android".equals(callerPackage)) {
16151                     throw new SecurityException("Given caller package " + callerPackage
16152                             + " is not running in process " + callerApp);
16153                 }
16154                 callingUid = callerApp.info.uid;
16155                 callingPid = callerApp.pid;
16156             } else {
16157                 callerPackage = null;
16158                 callingUid = Binder.getCallingUid();
16159                 callingPid = Binder.getCallingPid();
16160             }
16161
16162             userId = handleIncomingUser(callingPid, callingUid, userId,
16163                     true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
16164
16165             Iterator<String> actions = filter.actionsIterator();
16166             if (actions == null) {
16167                 ArrayList<String> noAction = new ArrayList<String>(1);
16168                 noAction.add(null);
16169                 actions = noAction.iterator();
16170             }
16171
16172             // Collect stickies of users
16173             int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
16174             while (actions.hasNext()) {
16175                 String action = actions.next();
16176                 for (int id : userIds) {
16177                     ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
16178                     if (stickies != null) {
16179                         ArrayList<Intent> intents = stickies.get(action);
16180                         if (intents != null) {
16181                             if (stickyIntents == null) {
16182                                 stickyIntents = new ArrayList<Intent>();
16183                             }
16184                             stickyIntents.addAll(intents);
16185                         }
16186                     }
16187                 }
16188             }
16189         }
16190
16191         ArrayList<Intent> allSticky = null;
16192         if (stickyIntents != null) {
16193             final ContentResolver resolver = mContext.getContentResolver();
16194             // Look for any matching sticky broadcasts...
16195             for (int i = 0, N = stickyIntents.size(); i < N; i++) {
16196                 Intent intent = stickyIntents.get(i);
16197                 // If intent has scheme "content", it will need to acccess
16198                 // provider that needs to lock mProviderMap in ActivityThread
16199                 // and also it may need to wait application response, so we
16200                 // cannot lock ActivityManagerService here.
16201                 if (filter.match(resolver, intent, true, TAG) >= 0) {
16202                     if (allSticky == null) {
16203                         allSticky = new ArrayList<Intent>();
16204                     }
16205                     allSticky.add(intent);
16206                 }
16207             }
16208         }
16209
16210         // The first sticky in the list is returned directly back to the client.
16211         Intent sticky = allSticky != null ? allSticky.get(0) : null;
16212         if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
16213         if (receiver == null) {
16214             return sticky;
16215         }
16216
16217         synchronized (this) {
16218             if (callerApp != null && (callerApp.thread == null
16219                     || callerApp.thread.asBinder() != caller.asBinder())) {
16220                 // Original caller already died
16221                 return null;
16222             }
16223             ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
16224             if (rl == null) {
16225                 rl = new ReceiverList(this, callerApp, callingPid, callingUid,
16226                         userId, receiver);
16227                 if (rl.app != null) {
16228                     rl.app.receivers.add(rl);
16229                 } else {
16230                     try {
16231                         receiver.asBinder().linkToDeath(rl, 0);
16232                     } catch (RemoteException e) {
16233                         return sticky;
16234                     }
16235                     rl.linkedToDeath = true;
16236                 }
16237                 mRegisteredReceivers.put(receiver.asBinder(), rl);
16238             } else if (rl.uid != callingUid) {
16239                 throw new IllegalArgumentException(
16240                         "Receiver requested to register for uid " + callingUid
16241                         + " was previously registered for uid " + rl.uid);
16242             } else if (rl.pid != callingPid) {
16243                 throw new IllegalArgumentException(
16244                         "Receiver requested to register for pid " + callingPid
16245                         + " was previously registered for pid " + rl.pid);
16246             } else if (rl.userId != userId) {
16247                 throw new IllegalArgumentException(
16248                         "Receiver requested to register for user " + userId
16249                         + " was previously registered for user " + rl.userId);
16250             }
16251             BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
16252                     permission, callingUid, userId);
16253             rl.add(bf);
16254             if (!bf.debugCheck()) {
16255                 Slog.w(TAG, "==> For Dynamic broadcast");
16256             }
16257             mReceiverResolver.addFilter(bf);
16258
16259             // Enqueue broadcasts for all existing stickies that match
16260             // this filter.
16261             if (allSticky != null) {
16262                 ArrayList receivers = new ArrayList();
16263                 receivers.add(bf);
16264
16265                 final int stickyCount = allSticky.size();
16266                 for (int i = 0; i < stickyCount; i++) {
16267                     Intent intent = allSticky.get(i);
16268                     BroadcastQueue queue = broadcastQueueForIntent(intent);
16269                     BroadcastRecord r = new BroadcastRecord(queue, intent, null,
16270                             null, -1, -1, null, null, AppOpsManager.OP_NONE, null, receivers,
16271                             null, 0, null, null, false, true, true, -1);
16272                     queue.enqueueParallelBroadcastLocked(r);
16273                     queue.scheduleBroadcastsLocked();
16274                 }
16275             }
16276
16277             return sticky;
16278         }
16279     }
16280
16281     public void unregisterReceiver(IIntentReceiver receiver) {
16282         if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
16283
16284         final long origId = Binder.clearCallingIdentity();
16285         try {
16286             boolean doTrim = false;
16287
16288             synchronized(this) {
16289                 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
16290                 if (rl != null) {
16291                     final BroadcastRecord r = rl.curBroadcast;
16292                     if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
16293                         final boolean doNext = r.queue.finishReceiverLocked(
16294                                 r, r.resultCode, r.resultData, r.resultExtras,
16295                                 r.resultAbort, false);
16296                         if (doNext) {
16297                             doTrim = true;
16298                             r.queue.processNextBroadcast(false);
16299                         }
16300                     }
16301
16302                     if (rl.app != null) {
16303                         rl.app.receivers.remove(rl);
16304                     }
16305                     removeReceiverLocked(rl);
16306                     if (rl.linkedToDeath) {
16307                         rl.linkedToDeath = false;
16308                         rl.receiver.asBinder().unlinkToDeath(rl, 0);
16309                     }
16310                 }
16311             }
16312
16313             // If we actually concluded any broadcasts, we might now be able
16314             // to trim the recipients' apps from our working set
16315             if (doTrim) {
16316                 trimApplications();
16317                 return;
16318             }
16319
16320         } finally {
16321             Binder.restoreCallingIdentity(origId);
16322         }
16323     }
16324
16325     void removeReceiverLocked(ReceiverList rl) {
16326         mRegisteredReceivers.remove(rl.receiver.asBinder());
16327         for (int i = rl.size() - 1; i >= 0; i--) {
16328             mReceiverResolver.removeFilter(rl.get(i));
16329         }
16330     }
16331
16332     private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
16333         for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
16334             ProcessRecord r = mLruProcesses.get(i);
16335             if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
16336                 try {
16337                     r.thread.dispatchPackageBroadcast(cmd, packages);
16338                 } catch (RemoteException ex) {
16339                 }
16340             }
16341         }
16342     }
16343
16344     private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
16345             int callingUid, int[] users) {
16346         List<ResolveInfo> receivers = null;
16347         try {
16348             HashSet<ComponentName> singleUserReceivers = null;
16349             boolean scannedFirstReceivers = false;
16350             for (int user : users) {
16351                 // Skip users that have Shell restrictions
16352                 if (callingUid == Process.SHELL_UID
16353                         && getUserManagerLocked().hasUserRestriction(
16354                                 UserManager.DISALLOW_DEBUGGING_FEATURES, user)) {
16355                     continue;
16356                 }
16357                 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
16358                         .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
16359                 if (user != UserHandle.USER_OWNER && newReceivers != null) {
16360                     // If this is not the primary user, we need to check for
16361                     // any receivers that should be filtered out.
16362                     for (int i=0; i<newReceivers.size(); i++) {
16363                         ResolveInfo ri = newReceivers.get(i);
16364                         if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
16365                             newReceivers.remove(i);
16366                             i--;
16367                         }
16368                     }
16369                 }
16370                 if (newReceivers != null && newReceivers.size() == 0) {
16371                     newReceivers = null;
16372                 }
16373                 if (receivers == null) {
16374                     receivers = newReceivers;
16375                 } else if (newReceivers != null) {
16376                     // We need to concatenate the additional receivers
16377                     // found with what we have do far.  This would be easy,
16378                     // but we also need to de-dup any receivers that are
16379                     // singleUser.
16380                     if (!scannedFirstReceivers) {
16381                         // Collect any single user receivers we had already retrieved.
16382                         scannedFirstReceivers = true;
16383                         for (int i=0; i<receivers.size(); i++) {
16384                             ResolveInfo ri = receivers.get(i);
16385                             if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
16386                                 ComponentName cn = new ComponentName(
16387                                         ri.activityInfo.packageName, ri.activityInfo.name);
16388                                 if (singleUserReceivers == null) {
16389                                     singleUserReceivers = new HashSet<ComponentName>();
16390                                 }
16391                                 singleUserReceivers.add(cn);
16392                             }
16393                         }
16394                     }
16395                     // Add the new results to the existing results, tracking
16396                     // and de-dupping single user receivers.
16397                     for (int i=0; i<newReceivers.size(); i++) {
16398                         ResolveInfo ri = newReceivers.get(i);
16399                         if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
16400                             ComponentName cn = new ComponentName(
16401                                     ri.activityInfo.packageName, ri.activityInfo.name);
16402                             if (singleUserReceivers == null) {
16403                                 singleUserReceivers = new HashSet<ComponentName>();
16404                             }
16405                             if (!singleUserReceivers.contains(cn)) {
16406                                 singleUserReceivers.add(cn);
16407                                 receivers.add(ri);
16408                             }
16409                         } else {
16410                             receivers.add(ri);
16411                         }
16412                     }
16413                 }
16414             }
16415         } catch (RemoteException ex) {
16416             // pm is in same process, this will never happen.
16417         }
16418         return receivers;
16419     }
16420
16421     private final int broadcastIntentLocked(ProcessRecord callerApp,
16422             String callerPackage, Intent intent, String resolvedType,
16423             IIntentReceiver resultTo, int resultCode, String resultData,
16424             Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle options,
16425             boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
16426         intent = new Intent(intent);
16427
16428         // By default broadcasts do not go to stopped apps.
16429         intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
16430
16431         // If we have not finished booting, don't allow this to launch new processes.
16432         if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
16433             intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16434         }
16435
16436         if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
16437                 (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
16438                 + " ordered=" + ordered + " userid=" + userId);
16439         if ((resultTo != null) && !ordered) {
16440             Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
16441         }
16442
16443         userId = handleIncomingUser(callingPid, callingUid, userId,
16444                 true, ALLOW_NON_FULL, "broadcast", callerPackage);
16445
16446         // Make sure that the user who is receiving this broadcast is running.
16447         // If not, we will just skip it. Make an exception for shutdown broadcasts
16448         // and upgrade steps.
16449
16450         if (userId != UserHandle.USER_ALL && !isUserRunningLocked(userId, false)) {
16451             if ((callingUid != Process.SYSTEM_UID
16452                     || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
16453                     && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
16454                 Slog.w(TAG, "Skipping broadcast of " + intent
16455                         + ": user " + userId + " is stopped");
16456                 return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
16457             }
16458         }
16459
16460         BroadcastOptions brOptions = null;
16461         if (options != null) {
16462             brOptions = new BroadcastOptions(options);
16463             if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
16464                 // See if the caller is allowed to do this.  Note we are checking against
16465                 // the actual real caller (not whoever provided the operation as say a
16466                 // PendingIntent), because that who is actually supplied the arguments.
16467                 if (checkComponentPermission(
16468                         android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
16469                         Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
16470                         != PackageManager.PERMISSION_GRANTED) {
16471                     String msg = "Permission Denial: " + intent.getAction()
16472                             + " broadcast from " + callerPackage + " (pid=" + callingPid
16473                             + ", uid=" + callingUid + ")"
16474                             + " requires "
16475                             + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
16476                     Slog.w(TAG, msg);
16477                     throw new SecurityException(msg);
16478                 }
16479             }
16480         }
16481
16482         /*
16483          * Prevent non-system code (defined here to be non-persistent
16484          * processes) from sending protected broadcasts.
16485          */
16486         int callingAppId = UserHandle.getAppId(callingUid);
16487         if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
16488             || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
16489             || callingAppId == Process.NFC_UID || callingUid == 0) {
16490             // Always okay.
16491         } else if (callerApp == null || !callerApp.persistent) {
16492             try {
16493                 if (AppGlobals.getPackageManager().isProtectedBroadcast(
16494                         intent.getAction())) {
16495                     String msg = "Permission Denial: not allowed to send broadcast "
16496                             + intent.getAction() + " from pid="
16497                             + callingPid + ", uid=" + callingUid;
16498                     Slog.w(TAG, msg);
16499                     throw new SecurityException(msg);
16500                 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
16501                     // Special case for compatibility: we don't want apps to send this,
16502                     // but historically it has not been protected and apps may be using it
16503                     // to poke their own app widget.  So, instead of making it protected,
16504                     // just limit it to the caller.
16505                     if (callerApp == null) {
16506                         String msg = "Permission Denial: not allowed to send broadcast "
16507                                 + intent.getAction() + " from unknown caller.";
16508                         Slog.w(TAG, msg);
16509                         throw new SecurityException(msg);
16510                     } else if (intent.getComponent() != null) {
16511                         // They are good enough to send to an explicit component...  verify
16512                         // it is being sent to the calling app.
16513                         if (!intent.getComponent().getPackageName().equals(
16514                                 callerApp.info.packageName)) {
16515                             String msg = "Permission Denial: not allowed to send broadcast "
16516                                     + intent.getAction() + " to "
16517                                     + intent.getComponent().getPackageName() + " from "
16518                                     + callerApp.info.packageName;
16519                             Slog.w(TAG, msg);
16520                             throw new SecurityException(msg);
16521                         }
16522                     } else {
16523                         // Limit broadcast to their own package.
16524                         intent.setPackage(callerApp.info.packageName);
16525                     }
16526                 }
16527             } catch (RemoteException e) {
16528                 Slog.w(TAG, "Remote exception", e);
16529                 return ActivityManager.BROADCAST_SUCCESS;
16530             }
16531         }
16532
16533         final String action = intent.getAction();
16534         if (action != null) {
16535             switch (action) {
16536                 case Intent.ACTION_UID_REMOVED:
16537                 case Intent.ACTION_PACKAGE_REMOVED:
16538                 case Intent.ACTION_PACKAGE_CHANGED:
16539                 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
16540                 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
16541                     // Handle special intents: if this broadcast is from the package
16542                     // manager about a package being removed, we need to remove all of
16543                     // its activities from the history stack.
16544                     if (checkComponentPermission(
16545                             android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
16546                             callingPid, callingUid, -1, true)
16547                             != PackageManager.PERMISSION_GRANTED) {
16548                         String msg = "Permission Denial: " + intent.getAction()
16549                                 + " broadcast from " + callerPackage + " (pid=" + callingPid
16550                                 + ", uid=" + callingUid + ")"
16551                                 + " requires "
16552                                 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
16553                         Slog.w(TAG, msg);
16554                         throw new SecurityException(msg);
16555                     }
16556                     switch (action) {
16557                         case Intent.ACTION_UID_REMOVED:
16558                             final Bundle intentExtras = intent.getExtras();
16559                             final int uid = intentExtras != null
16560                                     ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
16561                             if (uid >= 0) {
16562                                 mBatteryStatsService.removeUid(uid);
16563                                 mAppOpsService.uidRemoved(uid);
16564                             }
16565                             break;
16566                         case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
16567                             // If resources are unavailable just force stop all those packages
16568                             // and flush the attribute cache as well.
16569                             String list[] =
16570                                     intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
16571                             if (list != null && list.length > 0) {
16572                                 for (int i = 0; i < list.length; i++) {
16573                                     forceStopPackageLocked(list[i], -1, false, true, true,
16574                                             false, false, userId, "storage unmount");
16575                                 }
16576                                 mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
16577                                 sendPackageBroadcastLocked(
16578                                         IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
16579                                         userId);
16580                             }
16581                             break;
16582                         case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
16583                             mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
16584                             break;
16585                         case Intent.ACTION_PACKAGE_REMOVED:
16586                         case Intent.ACTION_PACKAGE_CHANGED:
16587                             Uri data = intent.getData();
16588                             String ssp;
16589                             if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
16590                                 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
16591                                 boolean fullUninstall = removed &&
16592                                         !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
16593                                 final boolean killProcess =
16594                                         !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
16595                                 if (killProcess) {
16596                                     forceStopPackageLocked(ssp, UserHandle.getAppId(
16597                                             intent.getIntExtra(Intent.EXTRA_UID, -1)),
16598                                             false, true, true, false, fullUninstall, userId,
16599                                             removed ? "pkg removed" : "pkg changed");
16600                                 }
16601                                 if (removed) {
16602                                     sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
16603                                             new String[] {ssp}, userId);
16604                                     if (fullUninstall) {
16605                                         mAppOpsService.packageRemoved(
16606                                                 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
16607
16608                                         // Remove all permissions granted from/to this package
16609                                         removeUriPermissionsForPackageLocked(ssp, userId, true);
16610
16611                                         removeTasksByPackageNameLocked(ssp, userId);
16612                                         mBatteryStatsService.notePackageUninstalled(ssp);
16613                                     }
16614                                 } else {
16615                                     cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
16616                                             intent.getStringArrayExtra(
16617                                                     Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
16618                                 }
16619                             }
16620                             break;
16621                     }
16622                     break;
16623                 case Intent.ACTION_PACKAGE_ADDED:
16624                     // Special case for adding a package: by default turn on compatibility mode.
16625                     Uri data = intent.getData();
16626                     String ssp;
16627                     if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
16628                         final boolean replacing =
16629                                 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
16630                         mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
16631
16632                         try {
16633                             ApplicationInfo ai = AppGlobals.getPackageManager().
16634                                     getApplicationInfo(ssp, 0, 0);
16635                             mBatteryStatsService.notePackageInstalled(ssp,
16636                                     ai != null ? ai.versionCode : 0);
16637                         } catch (RemoteException e) {
16638                         }
16639                     }
16640                     break;
16641                 case Intent.ACTION_TIMEZONE_CHANGED:
16642                     // If this is the time zone changed action, queue up a message that will reset
16643                     // the timezone of all currently running processes. This message will get
16644                     // queued up before the broadcast happens.
16645                     mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
16646                     break;
16647                 case Intent.ACTION_TIME_CHANGED:
16648                     // If the user set the time, let all running processes know.
16649                     final int is24Hour =
16650                             intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
16651                                     : 0;
16652                     mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
16653                     BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16654                     synchronized (stats) {
16655                         stats.noteCurrentTimeChangedLocked();
16656                     }
16657                     break;
16658                 case Intent.ACTION_CLEAR_DNS_CACHE:
16659                     mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
16660                     break;
16661                 case Proxy.PROXY_CHANGE_ACTION:
16662                     ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
16663                     mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
16664                     break;
16665             }
16666         }
16667
16668         // Add to the sticky list if requested.
16669         if (sticky) {
16670             if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
16671                     callingPid, callingUid)
16672                     != PackageManager.PERMISSION_GRANTED) {
16673                 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
16674                         + callingPid + ", uid=" + callingUid
16675                         + " requires " + android.Manifest.permission.BROADCAST_STICKY;
16676                 Slog.w(TAG, msg);
16677                 throw new SecurityException(msg);
16678             }
16679             if (requiredPermissions != null && requiredPermissions.length > 0) {
16680                 Slog.w(TAG, "Can't broadcast sticky intent " + intent
16681                         + " and enforce permissions " + Arrays.toString(requiredPermissions));
16682                 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
16683             }
16684             if (intent.getComponent() != null) {
16685                 throw new SecurityException(
16686                         "Sticky broadcasts can't target a specific component");
16687             }
16688             // We use userId directly here, since the "all" target is maintained
16689             // as a separate set of sticky broadcasts.
16690             if (userId != UserHandle.USER_ALL) {
16691                 // But first, if this is not a broadcast to all users, then
16692                 // make sure it doesn't conflict with an existing broadcast to
16693                 // all users.
16694                 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
16695                         UserHandle.USER_ALL);
16696                 if (stickies != null) {
16697                     ArrayList<Intent> list = stickies.get(intent.getAction());
16698                     if (list != null) {
16699                         int N = list.size();
16700                         int i;
16701                         for (i=0; i<N; i++) {
16702                             if (intent.filterEquals(list.get(i))) {
16703                                 throw new IllegalArgumentException(
16704                                         "Sticky broadcast " + intent + " for user "
16705                                         + userId + " conflicts with existing global broadcast");
16706                             }
16707                         }
16708                     }
16709                 }
16710             }
16711             ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
16712             if (stickies == null) {
16713                 stickies = new ArrayMap<>();
16714                 mStickyBroadcasts.put(userId, stickies);
16715             }
16716             ArrayList<Intent> list = stickies.get(intent.getAction());
16717             if (list == null) {
16718                 list = new ArrayList<>();
16719                 stickies.put(intent.getAction(), list);
16720             }
16721             final int stickiesCount = list.size();
16722             int i;
16723             for (i = 0; i < stickiesCount; i++) {
16724                 if (intent.filterEquals(list.get(i))) {
16725                     // This sticky already exists, replace it.
16726                     list.set(i, new Intent(intent));
16727                     break;
16728                 }
16729             }
16730             if (i >= stickiesCount) {
16731                 list.add(new Intent(intent));
16732             }
16733         }
16734
16735         int[] users;
16736         if (userId == UserHandle.USER_ALL) {
16737             // Caller wants broadcast to go to all started users.
16738             users = mStartedUserArray;
16739         } else {
16740             // Caller wants broadcast to go to one specific user.
16741             users = new int[] {userId};
16742         }
16743
16744         // Figure out who all will receive this broadcast.
16745         List receivers = null;
16746         List<BroadcastFilter> registeredReceivers = null;
16747         // Need to resolve the intent to interested receivers...
16748         if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
16749                  == 0) {
16750             receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
16751         }
16752         if (intent.getComponent() == null) {
16753             if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
16754                 // Query one target user at a time, excluding shell-restricted users
16755                 UserManagerService ums = getUserManagerLocked();
16756                 for (int i = 0; i < users.length; i++) {
16757                     if (ums.hasUserRestriction(
16758                             UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
16759                         continue;
16760                     }
16761                     List<BroadcastFilter> registeredReceiversForUser =
16762                             mReceiverResolver.queryIntent(intent,
16763                                     resolvedType, false, users[i]);
16764                     if (registeredReceivers == null) {
16765                         registeredReceivers = registeredReceiversForUser;
16766                     } else if (registeredReceiversForUser != null) {
16767                         registeredReceivers.addAll(registeredReceiversForUser);
16768                     }
16769                 }
16770             } else {
16771                 registeredReceivers = mReceiverResolver.queryIntent(intent,
16772                         resolvedType, false, userId);
16773             }
16774         }
16775
16776         final boolean replacePending =
16777                 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
16778
16779         if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueing broadcast: " + intent.getAction()
16780                 + " replacePending=" + replacePending);
16781
16782         int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
16783         if (!ordered && NR > 0) {
16784             // If we are not serializing this broadcast, then send the
16785             // registered receivers separately so they don't wait for the
16786             // components to be launched.
16787             final BroadcastQueue queue = broadcastQueueForIntent(intent);
16788             BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
16789                     callerPackage, callingPid, callingUid, resolvedType, requiredPermissions,
16790                     appOp, brOptions, registeredReceivers, resultTo, resultCode, resultData,
16791                     resultExtras, ordered, sticky, false, userId);
16792             if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
16793             final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
16794             if (!replaced) {
16795                 queue.enqueueParallelBroadcastLocked(r);
16796                 queue.scheduleBroadcastsLocked();
16797             }
16798             registeredReceivers = null;
16799             NR = 0;
16800         }
16801
16802         // Merge into one list.
16803         int ir = 0;
16804         if (receivers != null) {
16805             // A special case for PACKAGE_ADDED: do not allow the package
16806             // being added to see this broadcast.  This prevents them from
16807             // using this as a back door to get run as soon as they are
16808             // installed.  Maybe in the future we want to have a special install
16809             // broadcast or such for apps, but we'd like to deliberately make
16810             // this decision.
16811             String skipPackages[] = null;
16812             if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
16813                     || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
16814                     || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
16815                 Uri data = intent.getData();
16816                 if (data != null) {
16817                     String pkgName = data.getSchemeSpecificPart();
16818                     if (pkgName != null) {
16819                         skipPackages = new String[] { pkgName };
16820                     }
16821                 }
16822             } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
16823                 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
16824             }
16825             if (skipPackages != null && (skipPackages.length > 0)) {
16826                 for (String skipPackage : skipPackages) {
16827                     if (skipPackage != null) {
16828                         int NT = receivers.size();
16829                         for (int it=0; it<NT; it++) {
16830                             ResolveInfo curt = (ResolveInfo)receivers.get(it);
16831                             if (curt.activityInfo.packageName.equals(skipPackage)) {
16832                                 receivers.remove(it);
16833                                 it--;
16834                                 NT--;
16835                             }
16836                         }
16837                     }
16838                 }
16839             }
16840
16841             int NT = receivers != null ? receivers.size() : 0;
16842             int it = 0;
16843             ResolveInfo curt = null;
16844             BroadcastFilter curr = null;
16845             while (it < NT && ir < NR) {
16846                 if (curt == null) {
16847                     curt = (ResolveInfo)receivers.get(it);
16848                 }
16849                 if (curr == null) {
16850                     curr = registeredReceivers.get(ir);
16851                 }
16852                 if (curr.getPriority() >= curt.priority) {
16853                     // Insert this broadcast record into the final list.
16854                     receivers.add(it, curr);
16855                     ir++;
16856                     curr = null;
16857                     it++;
16858                     NT++;
16859                 } else {
16860                     // Skip to the next ResolveInfo in the final list.
16861                     it++;
16862                     curt = null;
16863                 }
16864             }
16865         }
16866         while (ir < NR) {
16867             if (receivers == null) {
16868                 receivers = new ArrayList();
16869             }
16870             receivers.add(registeredReceivers.get(ir));
16871             ir++;
16872         }
16873
16874         if ((receivers != null && receivers.size() > 0)
16875                 || resultTo != null) {
16876             BroadcastQueue queue = broadcastQueueForIntent(intent);
16877             BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
16878                     callerPackage, callingPid, callingUid, resolvedType,
16879                     requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
16880                     resultData, resultExtras, ordered, sticky, false, userId);
16881
16882             if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
16883                     + ": prev had " + queue.mOrderedBroadcasts.size());
16884             if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
16885                     "Enqueueing broadcast " + r.intent.getAction());
16886
16887             boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
16888             if (!replaced) {
16889                 queue.enqueueOrderedBroadcastLocked(r);
16890                 queue.scheduleBroadcastsLocked();
16891             }
16892         }
16893
16894         return ActivityManager.BROADCAST_SUCCESS;
16895     }
16896
16897     final Intent verifyBroadcastLocked(Intent intent) {
16898         // Refuse possible leaked file descriptors
16899         if (intent != null && intent.hasFileDescriptors() == true) {
16900             throw new IllegalArgumentException("File descriptors passed in Intent");
16901         }
16902
16903         int flags = intent.getFlags();
16904
16905         if (!mProcessesReady) {
16906             // if the caller really truly claims to know what they're doing, go
16907             // ahead and allow the broadcast without launching any receivers
16908             if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
16909                 // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
16910             } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
16911                 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
16912                         + " before boot completion");
16913                 throw new IllegalStateException("Cannot broadcast before boot completed");
16914             }
16915         }
16916
16917         if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
16918             throw new IllegalArgumentException(
16919                     "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
16920         }
16921
16922         return intent;
16923     }
16924
16925     public final int broadcastIntent(IApplicationThread caller,
16926             Intent intent, String resolvedType, IIntentReceiver resultTo,
16927             int resultCode, String resultData, Bundle resultExtras,
16928             String[] requiredPermissions, int appOp, Bundle options,
16929             boolean serialized, boolean sticky, int userId) {
16930         enforceNotIsolatedCaller("broadcastIntent");
16931         synchronized(this) {
16932             intent = verifyBroadcastLocked(intent);
16933
16934             final ProcessRecord callerApp = getRecordForAppLocked(caller);
16935             final int callingPid = Binder.getCallingPid();
16936             final int callingUid = Binder.getCallingUid();
16937             final long origId = Binder.clearCallingIdentity();
16938             int res = broadcastIntentLocked(callerApp,
16939                     callerApp != null ? callerApp.info.packageName : null,
16940                     intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
16941                     requiredPermissions, appOp, null, serialized, sticky,
16942                     callingPid, callingUid, userId);
16943             Binder.restoreCallingIdentity(origId);
16944             return res;
16945         }
16946     }
16947
16948
16949     int broadcastIntentInPackage(String packageName, int uid,
16950             Intent intent, String resolvedType, IIntentReceiver resultTo,
16951             int resultCode, String resultData, Bundle resultExtras,
16952             String requiredPermission, Bundle options, boolean serialized, boolean sticky,
16953             int userId) {
16954         synchronized(this) {
16955             intent = verifyBroadcastLocked(intent);
16956
16957             final long origId = Binder.clearCallingIdentity();
16958             String[] requiredPermissions = requiredPermission == null ? null
16959                     : new String[] {requiredPermission};
16960             int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
16961                     resultTo, resultCode, resultData, resultExtras,
16962                     requiredPermissions, AppOpsManager.OP_NONE, options, serialized,
16963                     sticky, -1, uid, userId);
16964             Binder.restoreCallingIdentity(origId);
16965             return res;
16966         }
16967     }
16968
16969     public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
16970         // Refuse possible leaked file descriptors
16971         if (intent != null && intent.hasFileDescriptors() == true) {
16972             throw new IllegalArgumentException("File descriptors passed in Intent");
16973         }
16974
16975         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16976                 userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
16977
16978         synchronized(this) {
16979             if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
16980                     != PackageManager.PERMISSION_GRANTED) {
16981                 String msg = "Permission Denial: unbroadcastIntent() from pid="
16982                         + Binder.getCallingPid()
16983                         + ", uid=" + Binder.getCallingUid()
16984                         + " requires " + android.Manifest.permission.BROADCAST_STICKY;
16985                 Slog.w(TAG, msg);
16986                 throw new SecurityException(msg);
16987             }
16988             ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
16989             if (stickies != null) {
16990                 ArrayList<Intent> list = stickies.get(intent.getAction());
16991                 if (list != null) {
16992                     int N = list.size();
16993                     int i;
16994                     for (i=0; i<N; i++) {
16995                         if (intent.filterEquals(list.get(i))) {
16996                             list.remove(i);
16997                             break;
16998                         }
16999                     }
17000                     if (list.size() <= 0) {
17001                         stickies.remove(intent.getAction());
17002                     }
17003                 }
17004                 if (stickies.size() <= 0) {
17005                     mStickyBroadcasts.remove(userId);
17006                 }
17007             }
17008         }
17009     }
17010
17011     void backgroundServicesFinishedLocked(int userId) {
17012         for (BroadcastQueue queue : mBroadcastQueues) {
17013             queue.backgroundServicesFinishedLocked(userId);
17014         }
17015     }
17016
17017     public void finishReceiver(IBinder who, int resultCode, String resultData,
17018             Bundle resultExtras, boolean resultAbort, int flags) {
17019         if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
17020
17021         // Refuse possible leaked file descriptors
17022         if (resultExtras != null && resultExtras.hasFileDescriptors()) {
17023             throw new IllegalArgumentException("File descriptors passed in Bundle");
17024         }
17025
17026         final long origId = Binder.clearCallingIdentity();
17027         try {
17028             boolean doNext = false;
17029             BroadcastRecord r;
17030
17031             synchronized(this) {
17032                 BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
17033                         ? mFgBroadcastQueue : mBgBroadcastQueue;
17034                 r = queue.getMatchingOrderedReceiver(who);
17035                 if (r != null) {
17036                     doNext = r.queue.finishReceiverLocked(r, resultCode,
17037                         resultData, resultExtras, resultAbort, true);
17038                 }
17039             }
17040
17041             if (doNext) {
17042                 r.queue.processNextBroadcast(false);
17043             }
17044             trimApplications();
17045         } finally {
17046             Binder.restoreCallingIdentity(origId);
17047         }
17048     }
17049
17050     // =========================================================
17051     // INSTRUMENTATION
17052     // =========================================================
17053
17054     public boolean startInstrumentation(ComponentName className,
17055             String profileFile, int flags, Bundle arguments,
17056             IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
17057             int userId, String abiOverride) {
17058         enforceNotIsolatedCaller("startInstrumentation");
17059         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17060                 userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
17061         // Refuse possible leaked file descriptors
17062         if (arguments != null && arguments.hasFileDescriptors()) {
17063             throw new IllegalArgumentException("File descriptors passed in Bundle");
17064         }
17065
17066         synchronized(this) {
17067             InstrumentationInfo ii = null;
17068             ApplicationInfo ai = null;
17069             try {
17070                 ii = mContext.getPackageManager().getInstrumentationInfo(
17071                     className, STOCK_PM_FLAGS);
17072                 ai = AppGlobals.getPackageManager().getApplicationInfo(
17073                         ii.targetPackage, STOCK_PM_FLAGS, userId);
17074             } catch (PackageManager.NameNotFoundException e) {
17075             } catch (RemoteException e) {
17076             }
17077             if (ii == null) {
17078                 reportStartInstrumentationFailure(watcher, className,
17079                         "Unable to find instrumentation info for: " + className);
17080                 return false;
17081             }
17082             if (ai == null) {
17083                 reportStartInstrumentationFailure(watcher, className,
17084                         "Unable to find instrumentation target package: " + ii.targetPackage);
17085                 return false;
17086             }
17087
17088             int match = mContext.getPackageManager().checkSignatures(
17089                     ii.targetPackage, ii.packageName);
17090             if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
17091                 String msg = "Permission Denial: starting instrumentation "
17092                         + className + " from pid="
17093                         + Binder.getCallingPid()
17094                         + ", uid=" + Binder.getCallingPid()
17095                         + " not allowed because package " + ii.packageName
17096                         + " does not have a signature matching the target "
17097                         + ii.targetPackage;
17098                 reportStartInstrumentationFailure(watcher, className, msg);
17099                 throw new SecurityException(msg);
17100             }
17101
17102             final long origId = Binder.clearCallingIdentity();
17103             // Instrumentation can kill and relaunch even persistent processes
17104             forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
17105                     "start instr");
17106             ProcessRecord app = addAppLocked(ai, false, abiOverride);
17107             app.instrumentationClass = className;
17108             app.instrumentationInfo = ai;
17109             app.instrumentationProfileFile = profileFile;
17110             app.instrumentationArguments = arguments;
17111             app.instrumentationWatcher = watcher;
17112             app.instrumentationUiAutomationConnection = uiAutomationConnection;
17113             app.instrumentationResultClass = className;
17114             Binder.restoreCallingIdentity(origId);
17115         }
17116
17117         return true;
17118     }
17119
17120     /**
17121      * Report errors that occur while attempting to start Instrumentation.  Always writes the
17122      * error to the logs, but if somebody is watching, send the report there too.  This enables
17123      * the "am" command to report errors with more information.
17124      *
17125      * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
17126      * @param cn The component name of the instrumentation.
17127      * @param report The error report.
17128      */
17129     private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
17130             ComponentName cn, String report) {
17131         Slog.w(TAG, report);
17132         try {
17133             if (watcher != null) {
17134                 Bundle results = new Bundle();
17135                 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
17136                 results.putString("Error", report);
17137                 watcher.instrumentationStatus(cn, -1, results);
17138             }
17139         } catch (RemoteException e) {
17140             Slog.w(TAG, e);
17141         }
17142     }
17143
17144     void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
17145         if (app.instrumentationWatcher != null) {
17146             try {
17147                 // NOTE:  IInstrumentationWatcher *must* be oneway here
17148                 app.instrumentationWatcher.instrumentationFinished(
17149                     app.instrumentationClass,
17150                     resultCode,
17151                     results);
17152             } catch (RemoteException e) {
17153             }
17154         }
17155
17156         // Can't call out of the system process with a lock held, so post a message.
17157         if (app.instrumentationUiAutomationConnection != null) {
17158             mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
17159                     app.instrumentationUiAutomationConnection).sendToTarget();
17160         }
17161
17162         app.instrumentationWatcher = null;
17163         app.instrumentationUiAutomationConnection = null;
17164         app.instrumentationClass = null;
17165         app.instrumentationInfo = null;
17166         app.instrumentationProfileFile = null;
17167         app.instrumentationArguments = null;
17168
17169         forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
17170                 "finished inst");
17171     }
17172
17173     public void finishInstrumentation(IApplicationThread target,
17174             int resultCode, Bundle results) {
17175         int userId = UserHandle.getCallingUserId();
17176         // Refuse possible leaked file descriptors
17177         if (results != null && results.hasFileDescriptors()) {
17178             throw new IllegalArgumentException("File descriptors passed in Intent");
17179         }
17180
17181         synchronized(this) {
17182             ProcessRecord app = getRecordForAppLocked(target);
17183             if (app == null) {
17184                 Slog.w(TAG, "finishInstrumentation: no app for " + target);
17185                 return;
17186             }
17187             final long origId = Binder.clearCallingIdentity();
17188             finishInstrumentationLocked(app, resultCode, results);
17189             Binder.restoreCallingIdentity(origId);
17190         }
17191     }
17192
17193     // =========================================================
17194     // CONFIGURATION
17195     // =========================================================
17196
17197     public ConfigurationInfo getDeviceConfigurationInfo() {
17198         ConfigurationInfo config = new ConfigurationInfo();
17199         synchronized (this) {
17200             config.reqTouchScreen = mConfiguration.touchscreen;
17201             config.reqKeyboardType = mConfiguration.keyboard;
17202             config.reqNavigation = mConfiguration.navigation;
17203             if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
17204                     || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
17205                 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
17206             }
17207             if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
17208                     && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
17209                 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
17210             }
17211             config.reqGlEsVersion = GL_ES_VERSION;
17212         }
17213         return config;
17214     }
17215
17216     ActivityStack getFocusedStack() {
17217         return mStackSupervisor.getFocusedStack();
17218     }
17219
17220     @Override
17221     public int getFocusedStackId() throws RemoteException {
17222         ActivityStack focusedStack = getFocusedStack();
17223         if (focusedStack != null) {
17224             return focusedStack.getStackId();
17225         }
17226         return -1;
17227     }
17228
17229     public Configuration getConfiguration() {
17230         Configuration ci;
17231         synchronized(this) {
17232             ci = new Configuration(mConfiguration);
17233             ci.userSetLocale = false;
17234         }
17235         return ci;
17236     }
17237
17238     public void updatePersistentConfiguration(Configuration values) {
17239         enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
17240                 "updateConfiguration()");
17241         enforceWriteSettingsPermission("updateConfiguration()");
17242         if (values == null) {
17243             throw new NullPointerException("Configuration must not be null");
17244         }
17245
17246         synchronized(this) {
17247             final long origId = Binder.clearCallingIdentity();
17248             updateConfigurationLocked(values, null, true, false);
17249             Binder.restoreCallingIdentity(origId);
17250         }
17251     }
17252
17253     private void enforceWriteSettingsPermission(String func) {
17254         int uid = Binder.getCallingUid();
17255         if (uid == Process.ROOT_UID) {
17256             return;
17257         }
17258
17259         if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
17260                 Settings.getPackageNameForUid(mContext, uid), false)) {
17261             return;
17262         }
17263
17264         String msg = "Permission Denial: " + func + " from pid="
17265                 + Binder.getCallingPid()
17266                 + ", uid=" + uid
17267                 + " requires " + android.Manifest.permission.WRITE_SETTINGS;
17268         Slog.w(TAG, msg);
17269         throw new SecurityException(msg);
17270     }
17271
17272     public void updateConfiguration(Configuration values) {
17273         enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
17274                 "updateConfiguration()");
17275
17276         synchronized(this) {
17277             if (values == null && mWindowManager != null) {
17278                 // sentinel: fetch the current configuration from the window manager
17279                 values = mWindowManager.computeNewConfiguration();
17280             }
17281
17282             if (mWindowManager != null) {
17283                 mProcessList.applyDisplaySize(mWindowManager);
17284             }
17285
17286             final long origId = Binder.clearCallingIdentity();
17287             if (values != null) {
17288                 Settings.System.clearConfiguration(values);
17289             }
17290             updateConfigurationLocked(values, null, false, false);
17291             Binder.restoreCallingIdentity(origId);
17292         }
17293     }
17294
17295     /**
17296      * Do either or both things: (1) change the current configuration, and (2)
17297      * make sure the given activity is running with the (now) current
17298      * configuration.  Returns true if the activity has been left running, or
17299      * false if <var>starting</var> is being destroyed to match the new
17300      * configuration.
17301      * @param persistent TODO
17302      */
17303     boolean updateConfigurationLocked(Configuration values,
17304             ActivityRecord starting, boolean persistent, boolean initLocale) {
17305         int changes = 0;
17306
17307         if (values != null) {
17308             Configuration newConfig = new Configuration(mConfiguration);
17309             changes = newConfig.updateFrom(values);
17310             if (changes != 0) {
17311                 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
17312                         "Updating configuration to: " + values);
17313
17314                 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
17315
17316                 if (!initLocale && values.locale != null && values.userSetLocale) {
17317                     final String languageTag = values.locale.toLanguageTag();
17318                     SystemProperties.set("persist.sys.locale", languageTag);
17319                     mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
17320                             values.locale));
17321                 }
17322
17323                 mConfigurationSeq++;
17324                 if (mConfigurationSeq <= 0) {
17325                     mConfigurationSeq = 1;
17326                 }
17327                 newConfig.seq = mConfigurationSeq;
17328                 mConfiguration = newConfig;
17329                 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
17330                 mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId);
17331                 //mUsageStatsService.noteStartConfig(newConfig);
17332
17333                 final Configuration configCopy = new Configuration(mConfiguration);
17334
17335                 // TODO: If our config changes, should we auto dismiss any currently
17336                 // showing dialogs?
17337                 mShowDialogs = shouldShowDialogs(newConfig);
17338
17339                 AttributeCache ac = AttributeCache.instance();
17340                 if (ac != null) {
17341                     ac.updateConfiguration(configCopy);
17342                 }
17343
17344                 // Make sure all resources in our process are updated
17345                 // right now, so that anyone who is going to retrieve
17346                 // resource values after we return will be sure to get
17347                 // the new ones.  This is especially important during
17348                 // boot, where the first config change needs to guarantee
17349                 // all resources have that config before following boot
17350                 // code is executed.
17351                 mSystemThread.applyConfigurationToResources(configCopy);
17352
17353                 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
17354                     Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
17355                     msg.obj = new Configuration(configCopy);
17356                     mHandler.sendMessage(msg);
17357                 }
17358
17359                 for (int i=mLruProcesses.size()-1; i>=0; i--) {
17360                     ProcessRecord app = mLruProcesses.get(i);
17361                     try {
17362                         if (app.thread != null) {
17363                             if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
17364                                     + app.processName + " new config " + mConfiguration);
17365                             app.thread.scheduleConfigurationChanged(configCopy);
17366                         }
17367                     } catch (Exception e) {
17368                     }
17369                 }
17370                 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
17371                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17372                         | Intent.FLAG_RECEIVER_REPLACE_PENDING
17373                         | Intent.FLAG_RECEIVER_FOREGROUND);
17374                 broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
17375                         null, AppOpsManager.OP_NONE, null, false, false,
17376                         MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17377                 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
17378                     intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
17379                     intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
17380                     if (!mProcessesReady) {
17381                         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17382                     }
17383                     broadcastIntentLocked(null, null, intent,
17384                             null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17385                             null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17386                 }
17387             }
17388         }
17389
17390         boolean kept = true;
17391         final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
17392         // mainStack is null during startup.
17393         if (mainStack != null) {
17394             if (changes != 0 && starting == null) {
17395                 // If the configuration changed, and the caller is not already
17396                 // in the process of starting an activity, then find the top
17397                 // activity to check if its configuration needs to change.
17398                 starting = mainStack.topRunningActivityLocked(null);
17399             }
17400
17401             if (starting != null) {
17402                 kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
17403                 // And we need to make sure at this point that all other activities
17404                 // are made visible with the correct configuration.
17405                 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
17406             }
17407         }
17408
17409         if (values != null && mWindowManager != null) {
17410             mWindowManager.setNewConfiguration(mConfiguration);
17411         }
17412
17413         return kept;
17414     }
17415
17416     /**
17417      * Decide based on the configuration whether we should shouw the ANR,
17418      * crash, etc dialogs.  The idea is that if there is no affordnace to
17419      * press the on-screen buttons, we shouldn't show the dialog.
17420      *
17421      * A thought: SystemUI might also want to get told about this, the Power
17422      * dialog / global actions also might want different behaviors.
17423      */
17424     private static final boolean shouldShowDialogs(Configuration config) {
17425         return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
17426                 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
17427                 && config.navigation == Configuration.NAVIGATION_NONAV);
17428     }
17429
17430     @Override
17431     public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
17432         synchronized (this) {
17433             ActivityRecord srec = ActivityRecord.forTokenLocked(token);
17434             if (srec != null) {
17435                 return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
17436             }
17437         }
17438         return false;
17439     }
17440
17441     public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
17442             Intent resultData) {
17443
17444         synchronized (this) {
17445             final ActivityRecord r = ActivityRecord.forTokenLocked(token);
17446             if (r != null) {
17447                 return r.task.stack.navigateUpToLocked(r, destIntent, resultCode, resultData);
17448             }
17449             return false;
17450         }
17451     }
17452
17453     public int getLaunchedFromUid(IBinder activityToken) {
17454         ActivityRecord srec;
17455         synchronized (this) {
17456             srec = ActivityRecord.forTokenLocked(activityToken);
17457         }
17458         if (srec == null) {
17459             return -1;
17460         }
17461         return srec.launchedFromUid;
17462     }
17463
17464     public String getLaunchedFromPackage(IBinder activityToken) {
17465         ActivityRecord srec;
17466         synchronized (this) {
17467             srec = ActivityRecord.forTokenLocked(activityToken);
17468         }
17469         if (srec == null) {
17470             return null;
17471         }
17472         return srec.launchedFromPackage;
17473     }
17474
17475     // =========================================================
17476     // LIFETIME MANAGEMENT
17477     // =========================================================
17478
17479     // Returns which broadcast queue the app is the current [or imminent] receiver
17480     // on, or 'null' if the app is not an active broadcast recipient.
17481     private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
17482         BroadcastRecord r = app.curReceiver;
17483         if (r != null) {
17484             return r.queue;
17485         }
17486
17487         // It's not the current receiver, but it might be starting up to become one
17488         synchronized (this) {
17489             for (BroadcastQueue queue : mBroadcastQueues) {
17490                 r = queue.mPendingBroadcast;
17491                 if (r != null && r.curApp == app) {
17492                     // found it; report which queue it's in
17493                     return queue;
17494                 }
17495             }
17496         }
17497
17498         return null;
17499     }
17500
17501     Association startAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
17502             ComponentName targetComponent, String targetProcess) {
17503         if (!mTrackingAssociations) {
17504             return null;
17505         }
17506         ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
17507                 = mAssociations.get(targetUid);
17508         if (components == null) {
17509             components = new ArrayMap<>();
17510             mAssociations.put(targetUid, components);
17511         }
17512         SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
17513         if (sourceUids == null) {
17514             sourceUids = new SparseArray<>();
17515             components.put(targetComponent, sourceUids);
17516         }
17517         ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
17518         if (sourceProcesses == null) {
17519             sourceProcesses = new ArrayMap<>();
17520             sourceUids.put(sourceUid, sourceProcesses);
17521         }
17522         Association ass = sourceProcesses.get(sourceProcess);
17523         if (ass == null) {
17524             ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
17525                     targetProcess);
17526             sourceProcesses.put(sourceProcess, ass);
17527         }
17528         ass.mCount++;
17529         ass.mNesting++;
17530         if (ass.mNesting == 1) {
17531             ass.mStartTime = SystemClock.uptimeMillis();
17532         }
17533         return ass;
17534     }
17535
17536     void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
17537             ComponentName targetComponent) {
17538         if (!mTrackingAssociations) {
17539             return;
17540         }
17541         ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
17542                 = mAssociations.get(targetUid);
17543         if (components == null) {
17544             return;
17545         }
17546         SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
17547         if (sourceUids == null) {
17548             return;
17549         }
17550         ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
17551         if (sourceProcesses == null) {
17552             return;
17553         }
17554         Association ass = sourceProcesses.get(sourceProcess);
17555         if (ass == null || ass.mNesting <= 0) {
17556             return;
17557         }
17558         ass.mNesting--;
17559         if (ass.mNesting == 0) {
17560             ass.mTime += SystemClock.uptimeMillis() - ass.mStartTime;
17561         }
17562     }
17563
17564     private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
17565             boolean doingAll, long now) {
17566         if (mAdjSeq == app.adjSeq) {
17567             // This adjustment has already been computed.
17568             return app.curRawAdj;
17569         }
17570
17571         if (app.thread == null) {
17572             app.adjSeq = mAdjSeq;
17573             app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17574             app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17575             return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
17576         }
17577
17578         app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
17579         app.adjSource = null;
17580         app.adjTarget = null;
17581         app.empty = false;
17582         app.cached = false;
17583
17584         final int activitiesSize = app.activities.size();
17585
17586         if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
17587             // The max adjustment doesn't allow this app to be anything
17588             // below foreground, so it is not worth doing work for it.
17589             app.adjType = "fixed";
17590             app.adjSeq = mAdjSeq;
17591             app.curRawAdj = app.maxAdj;
17592             app.foregroundActivities = false;
17593             app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
17594             app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
17595             // System processes can do UI, and when they do we want to have
17596             // them trim their memory after the user leaves the UI.  To
17597             // facilitate this, here we need to determine whether or not it
17598             // is currently showing UI.
17599             app.systemNoUi = true;
17600             if (app == TOP_APP) {
17601                 app.systemNoUi = false;
17602             } else if (activitiesSize > 0) {
17603                 for (int j = 0; j < activitiesSize; j++) {
17604                     final ActivityRecord r = app.activities.get(j);
17605                     if (r.visible) {
17606                         app.systemNoUi = false;
17607                     }
17608                 }
17609             }
17610             if (!app.systemNoUi) {
17611                 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
17612             }
17613             return (app.curAdj=app.maxAdj);
17614         }
17615
17616         app.systemNoUi = false;
17617
17618         final int PROCESS_STATE_TOP = mTopProcessState;
17619
17620         // Determine the importance of the process, starting with most
17621         // important to least, and assign an appropriate OOM adjustment.
17622         int adj;
17623         int schedGroup;
17624         int procState;
17625         boolean foregroundActivities = false;
17626         BroadcastQueue queue;
17627         if (app == TOP_APP) {
17628             // The last app on the list is the foreground app.
17629             adj = ProcessList.FOREGROUND_APP_ADJ;
17630             schedGroup = Process.THREAD_GROUP_DEFAULT;
17631             app.adjType = "top-activity";
17632             foregroundActivities = true;
17633             procState = PROCESS_STATE_TOP;
17634         } else if (app.instrumentationClass != null) {
17635             // Don't want to kill running instrumentation.
17636             adj = ProcessList.FOREGROUND_APP_ADJ;
17637             schedGroup = Process.THREAD_GROUP_DEFAULT;
17638             app.adjType = "instrumentation";
17639             procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
17640         } else if ((queue = isReceivingBroadcast(app)) != null) {
17641             // An app that is currently receiving a broadcast also
17642             // counts as being in the foreground for OOM killer purposes.
17643             // It's placed in a sched group based on the nature of the
17644             // broadcast as reflected by which queue it's active in.
17645             adj = ProcessList.FOREGROUND_APP_ADJ;
17646             schedGroup = (queue == mFgBroadcastQueue)
17647                     ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
17648             app.adjType = "broadcast";
17649             procState = ActivityManager.PROCESS_STATE_RECEIVER;
17650         } else if (app.executingServices.size() > 0) {
17651             // An app that is currently executing a service callback also
17652             // counts as being in the foreground.
17653             adj = ProcessList.FOREGROUND_APP_ADJ;
17654             schedGroup = app.execServicesFg ?
17655                     Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
17656             app.adjType = "exec-service";
17657             procState = ActivityManager.PROCESS_STATE_SERVICE;
17658             //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
17659         } else {
17660             // As far as we know the process is empty.  We may change our mind later.
17661             schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17662             // At this point we don't actually know the adjustment.  Use the cached adj
17663             // value that the caller wants us to.
17664             adj = cachedAdj;
17665             procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17666             app.cached = true;
17667             app.empty = true;
17668             app.adjType = "cch-empty";
17669         }
17670
17671         // Examine all activities if not already foreground.
17672         if (!foregroundActivities && activitiesSize > 0) {
17673             for (int j = 0; j < activitiesSize; j++) {
17674                 final ActivityRecord r = app.activities.get(j);
17675                 if (r.app != app) {
17676                     Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
17677                             + app + "?!? Using " + r.app + " instead.");
17678                     continue;
17679                 }
17680                 if (r.visible) {
17681                     // App has a visible activity; only upgrade adjustment.
17682                     if (adj > ProcessList.VISIBLE_APP_ADJ) {
17683                         adj = ProcessList.VISIBLE_APP_ADJ;
17684                         app.adjType = "visible";
17685                     }
17686                     if (procState > PROCESS_STATE_TOP) {
17687                         procState = PROCESS_STATE_TOP;
17688                     }
17689                     schedGroup = Process.THREAD_GROUP_DEFAULT;
17690                     app.cached = false;
17691                     app.empty = false;
17692                     foregroundActivities = true;
17693                     break;
17694                 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
17695                     if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17696                         adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17697                         app.adjType = "pausing";
17698                     }
17699                     if (procState > PROCESS_STATE_TOP) {
17700                         procState = PROCESS_STATE_TOP;
17701                     }
17702                     schedGroup = Process.THREAD_GROUP_DEFAULT;
17703                     app.cached = false;
17704                     app.empty = false;
17705                     foregroundActivities = true;
17706                 } else if (r.state == ActivityState.STOPPING) {
17707                     if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17708                         adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17709                         app.adjType = "stopping";
17710                     }
17711                     // For the process state, we will at this point consider the
17712                     // process to be cached.  It will be cached either as an activity
17713                     // or empty depending on whether the activity is finishing.  We do
17714                     // this so that we can treat the process as cached for purposes of
17715                     // memory trimming (determing current memory level, trim command to
17716                     // send to process) since there can be an arbitrary number of stopping
17717                     // processes and they should soon all go into the cached state.
17718                     if (!r.finishing) {
17719                         if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
17720                             procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
17721                         }
17722                     }
17723                     app.cached = false;
17724                     app.empty = false;
17725                     foregroundActivities = true;
17726                 } else {
17727                     if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
17728                         procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
17729                         app.adjType = "cch-act";
17730                     }
17731                 }
17732             }
17733         }
17734
17735         if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17736             if (app.foregroundServices) {
17737                 // The user is aware of this app, so make it visible.
17738                 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17739                 procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
17740                 app.cached = false;
17741                 app.adjType = "fg-service";
17742                 schedGroup = Process.THREAD_GROUP_DEFAULT;
17743             } else if (app.forcingToForeground != null) {
17744                 // The user is aware of this app, so make it visible.
17745                 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17746                 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17747                 app.cached = false;
17748                 app.adjType = "force-fg";
17749                 app.adjSource = app.forcingToForeground;
17750                 schedGroup = Process.THREAD_GROUP_DEFAULT;
17751             }
17752         }
17753
17754         if (app == mHeavyWeightProcess) {
17755             if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
17756                 // We don't want to kill the current heavy-weight process.
17757                 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
17758                 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17759                 app.cached = false;
17760                 app.adjType = "heavy";
17761             }
17762             if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
17763                 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
17764             }
17765         }
17766
17767         if (app == mHomeProcess) {
17768             if (adj > ProcessList.HOME_APP_ADJ) {
17769                 // This process is hosting what we currently consider to be the
17770                 // home app, so we don't want to let it go into the background.
17771                 adj = ProcessList.HOME_APP_ADJ;
17772                 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17773                 app.cached = false;
17774                 app.adjType = "home";
17775             }
17776             if (procState > ActivityManager.PROCESS_STATE_HOME) {
17777                 procState = ActivityManager.PROCESS_STATE_HOME;
17778             }
17779         }
17780
17781         if (app == mPreviousProcess && app.activities.size() > 0) {
17782             if (adj > ProcessList.PREVIOUS_APP_ADJ) {
17783                 // This was the previous process that showed UI to the user.
17784                 // We want to try to keep it around more aggressively, to give
17785                 // a good experience around switching between two apps.
17786                 adj = ProcessList.PREVIOUS_APP_ADJ;
17787                 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17788                 app.cached = false;
17789                 app.adjType = "previous";
17790             }
17791             if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
17792                 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
17793             }
17794         }
17795
17796         if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
17797                 + " reason=" + app.adjType);
17798
17799         // By default, we use the computed adjustment.  It may be changed if
17800         // there are applications dependent on our services or providers, but
17801         // this gives us a baseline and makes sure we don't get into an
17802         // infinite recursion.
17803         app.adjSeq = mAdjSeq;
17804         app.curRawAdj = adj;
17805         app.hasStartedServices = false;
17806
17807         if (mBackupTarget != null && app == mBackupTarget.app) {
17808             // If possible we want to avoid killing apps while they're being backed up
17809             if (adj > ProcessList.BACKUP_APP_ADJ) {
17810                 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
17811                 adj = ProcessList.BACKUP_APP_ADJ;
17812                 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
17813                     procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
17814                 }
17815                 app.adjType = "backup";
17816                 app.cached = false;
17817             }
17818             if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
17819                 procState = ActivityManager.PROCESS_STATE_BACKUP;
17820             }
17821         }
17822
17823         boolean mayBeTop = false;
17824
17825         for (int is = app.services.size()-1;
17826                 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17827                         || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17828                         || procState > ActivityManager.PROCESS_STATE_TOP);
17829                 is--) {
17830             ServiceRecord s = app.services.valueAt(is);
17831             if (s.startRequested) {
17832                 app.hasStartedServices = true;
17833                 if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
17834                     procState = ActivityManager.PROCESS_STATE_SERVICE;
17835                 }
17836                 if (app.hasShownUi && app != mHomeProcess) {
17837                     // If this process has shown some UI, let it immediately
17838                     // go to the LRU list because it may be pretty heavy with
17839                     // UI stuff.  We'll tag it with a label just to help
17840                     // debug and understand what is going on.
17841                     if (adj > ProcessList.SERVICE_ADJ) {
17842                         app.adjType = "cch-started-ui-services";
17843                     }
17844                 } else {
17845                     if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
17846                         // This service has seen some activity within
17847                         // recent memory, so we will keep its process ahead
17848                         // of the background processes.
17849                         if (adj > ProcessList.SERVICE_ADJ) {
17850                             adj = ProcessList.SERVICE_ADJ;
17851                             app.adjType = "started-services";
17852                             app.cached = false;
17853                         }
17854                     }
17855                     // If we have let the service slide into the background
17856                     // state, still have some text describing what it is doing
17857                     // even though the service no longer has an impact.
17858                     if (adj > ProcessList.SERVICE_ADJ) {
17859                         app.adjType = "cch-started-services";
17860                     }
17861                 }
17862             }
17863             for (int conni = s.connections.size()-1;
17864                     conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17865                             || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17866                             || procState > ActivityManager.PROCESS_STATE_TOP);
17867                     conni--) {
17868                 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
17869                 for (int i = 0;
17870                         i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
17871                                 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17872                                 || procState > ActivityManager.PROCESS_STATE_TOP);
17873                         i++) {
17874                     // XXX should compute this based on the max of
17875                     // all connected clients.
17876                     ConnectionRecord cr = clist.get(i);
17877                     if (cr.binding.client == app) {
17878                         // Binding to ourself is not interesting.
17879                         continue;
17880                     }
17881                     if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
17882                         ProcessRecord client = cr.binding.client;
17883                         int clientAdj = computeOomAdjLocked(client, cachedAdj,
17884                                 TOP_APP, doingAll, now);
17885                         int clientProcState = client.curProcState;
17886                         if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
17887                             // If the other app is cached for any reason, for purposes here
17888                             // we are going to consider it empty.  The specific cached state
17889                             // doesn't propagate except under certain conditions.
17890                             clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17891                         }
17892                         String adjType = null;
17893                         if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
17894                             // Not doing bind OOM management, so treat
17895                             // this guy more like a started service.
17896                             if (app.hasShownUi && app != mHomeProcess) {
17897                                 // If this process has shown some UI, let it immediately
17898                                 // go to the LRU list because it may be pretty heavy with
17899                                 // UI stuff.  We'll tag it with a label just to help
17900                                 // debug and understand what is going on.
17901                                 if (adj > clientAdj) {
17902                                     adjType = "cch-bound-ui-services";
17903                                 }
17904                                 app.cached = false;
17905                                 clientAdj = adj;
17906                                 clientProcState = procState;
17907                             } else {
17908                                 if (now >= (s.lastActivity
17909                                         + ActiveServices.MAX_SERVICE_INACTIVITY)) {
17910                                     // This service has not seen activity within
17911                                     // recent memory, so allow it to drop to the
17912                                     // LRU list if there is no other reason to keep
17913                                     // it around.  We'll also tag it with a label just
17914                                     // to help debug and undertand what is going on.
17915                                     if (adj > clientAdj) {
17916                                         adjType = "cch-bound-services";
17917                                     }
17918                                     clientAdj = adj;
17919                                 }
17920                             }
17921                         }
17922                         if (adj > clientAdj) {
17923                             // If this process has recently shown UI, and
17924                             // the process that is binding to it is less
17925                             // important than being visible, then we don't
17926                             // care about the binding as much as we care
17927                             // about letting this process get into the LRU
17928                             // list to be killed and restarted if needed for
17929                             // memory.
17930                             if (app.hasShownUi && app != mHomeProcess
17931                                     && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17932                                 adjType = "cch-bound-ui-services";
17933                             } else {
17934                                 if ((cr.flags&(Context.BIND_ABOVE_CLIENT
17935                                         |Context.BIND_IMPORTANT)) != 0) {
17936                                     adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
17937                                             ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
17938                                 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
17939                                         && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
17940                                         && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17941                                     adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17942                                 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
17943                                     adj = clientAdj;
17944                                 } else {
17945                                     if (adj > ProcessList.VISIBLE_APP_ADJ) {
17946                                         adj = ProcessList.VISIBLE_APP_ADJ;
17947                                     }
17948                                 }
17949                                 if (!client.cached) {
17950                                     app.cached = false;
17951                                 }
17952                                 adjType = "service";
17953                             }
17954                         }
17955                         if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
17956                             if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
17957                                 schedGroup = Process.THREAD_GROUP_DEFAULT;
17958                             }
17959                             if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
17960                                 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
17961                                     // Special handling of clients who are in the top state.
17962                                     // We *may* want to consider this process to be in the
17963                                     // top state as well, but only if there is not another
17964                                     // reason for it to be running.  Being on the top is a
17965                                     // special state, meaning you are specifically running
17966                                     // for the current top app.  If the process is already
17967                                     // running in the background for some other reason, it
17968                                     // is more important to continue considering it to be
17969                                     // in the background state.
17970                                     mayBeTop = true;
17971                                     clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17972                                 } else {
17973                                     // Special handling for above-top states (persistent
17974                                     // processes).  These should not bring the current process
17975                                     // into the top state, since they are not on top.  Instead
17976                                     // give them the best state after that.
17977                                     if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
17978                                         clientProcState =
17979                                                 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
17980                                     } else if (mWakefulness
17981                                                     == PowerManagerInternal.WAKEFULNESS_AWAKE &&
17982                                             (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
17983                                                     != 0) {
17984                                         clientProcState =
17985                                                 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
17986                                     } else {
17987                                         clientProcState =
17988                                                 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17989                                     }
17990                                 }
17991                             }
17992                         } else {
17993                             if (clientProcState <
17994                                     ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
17995                                 clientProcState =
17996                                         ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
17997                             }
17998                         }
17999                         if (procState > clientProcState) {
18000                             procState = clientProcState;
18001                         }
18002                         if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
18003                                 && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
18004                             app.pendingUiClean = true;
18005                         }
18006                         if (adjType != null) {
18007                             app.adjType = adjType;
18008                             app.adjTypeCode = ActivityManager.RunningAppProcessInfo
18009                                     .REASON_SERVICE_IN_USE;
18010                             app.adjSource = cr.binding.client;
18011                             app.adjSourceProcState = clientProcState;
18012                             app.adjTarget = s.name;
18013                         }
18014                     }
18015                     if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
18016                         app.treatLikeActivity = true;
18017                     }
18018                     final ActivityRecord a = cr.activity;
18019                     if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
18020                         if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
18021                                 (a.visible || a.state == ActivityState.RESUMED
18022                                  || a.state == ActivityState.PAUSING)) {
18023                             adj = ProcessList.FOREGROUND_APP_ADJ;
18024                             if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
18025                                 schedGroup = Process.THREAD_GROUP_DEFAULT;
18026                             }
18027                             app.cached = false;
18028                             app.adjType = "service";
18029                             app.adjTypeCode = ActivityManager.RunningAppProcessInfo
18030                                     .REASON_SERVICE_IN_USE;
18031                             app.adjSource = a;
18032                             app.adjSourceProcState = procState;
18033                             app.adjTarget = s.name;
18034                         }
18035                     }
18036                 }
18037             }
18038         }
18039
18040         for (int provi = app.pubProviders.size()-1;
18041                 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18042                         || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
18043                         || procState > ActivityManager.PROCESS_STATE_TOP);
18044                 provi--) {
18045             ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
18046             for (int i = cpr.connections.size()-1;
18047                     i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18048                             || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
18049                             || procState > ActivityManager.PROCESS_STATE_TOP);
18050                     i--) {
18051                 ContentProviderConnection conn = cpr.connections.get(i);
18052                 ProcessRecord client = conn.client;
18053                 if (client == app) {
18054                     // Being our own client is not interesting.
18055                     continue;
18056                 }
18057                 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
18058                 int clientProcState = client.curProcState;
18059                 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
18060                     // If the other app is cached for any reason, for purposes here
18061                     // we are going to consider it empty.
18062                     clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18063                 }
18064                 if (adj > clientAdj) {
18065                     if (app.hasShownUi && app != mHomeProcess
18066                             && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18067                         app.adjType = "cch-ui-provider";
18068                     } else {
18069                         adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
18070                                 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
18071                         app.adjType = "provider";
18072                     }
18073                     app.cached &= client.cached;
18074                     app.adjTypeCode = ActivityManager.RunningAppProcessInfo
18075                             .REASON_PROVIDER_IN_USE;
18076                     app.adjSource = client;
18077                     app.adjSourceProcState = clientProcState;
18078                     app.adjTarget = cpr.name;
18079                 }
18080                 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
18081                     if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
18082                         // Special handling of clients who are in the top state.
18083                         // We *may* want to consider this process to be in the
18084                         // top state as well, but only if there is not another
18085                         // reason for it to be running.  Being on the top is a
18086                         // special state, meaning you are specifically running
18087                         // for the current top app.  If the process is already
18088                         // running in the background for some other reason, it
18089                         // is more important to continue considering it to be
18090                         // in the background state.
18091                         mayBeTop = true;
18092                         clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18093                     } else {
18094                         // Special handling for above-top states (persistent
18095                         // processes).  These should not bring the current process
18096                         // into the top state, since they are not on top.  Instead
18097                         // give them the best state after that.
18098                         clientProcState =
18099                                 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18100                     }
18101                 }
18102                 if (procState > clientProcState) {
18103                     procState = clientProcState;
18104                 }
18105                 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
18106                     schedGroup = Process.THREAD_GROUP_DEFAULT;
18107                 }
18108             }
18109             // If the provider has external (non-framework) process
18110             // dependencies, ensure that its adjustment is at least
18111             // FOREGROUND_APP_ADJ.
18112             if (cpr.hasExternalProcessHandles()) {
18113                 if (adj > ProcessList.FOREGROUND_APP_ADJ) {
18114                     adj = ProcessList.FOREGROUND_APP_ADJ;
18115                     schedGroup = Process.THREAD_GROUP_DEFAULT;
18116                     app.cached = false;
18117                     app.adjType = "provider";
18118                     app.adjTarget = cpr.name;
18119                 }
18120                 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
18121                     procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18122                 }
18123             }
18124         }
18125
18126         if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
18127             // A client of one of our services or providers is in the top state.  We
18128             // *may* want to be in the top state, but not if we are already running in
18129             // the background for some other reason.  For the decision here, we are going
18130             // to pick out a few specific states that we want to remain in when a client
18131             // is top (states that tend to be longer-term) and otherwise allow it to go
18132             // to the top state.
18133             switch (procState) {
18134                 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
18135                 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
18136                 case ActivityManager.PROCESS_STATE_SERVICE:
18137                     // These all are longer-term states, so pull them up to the top
18138                     // of the background states, but not all the way to the top state.
18139                     procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18140                     break;
18141                 default:
18142                     // Otherwise, top is a better choice, so take it.
18143                     procState = ActivityManager.PROCESS_STATE_TOP;
18144                     break;
18145             }
18146         }
18147
18148         if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
18149             if (app.hasClientActivities) {
18150                 // This is a cached process, but with client activities.  Mark it so.
18151                 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
18152                 app.adjType = "cch-client-act";
18153             } else if (app.treatLikeActivity) {
18154                 // This is a cached process, but somebody wants us to treat it like it has
18155                 // an activity, okay!
18156                 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
18157                 app.adjType = "cch-as-act";
18158             }
18159         }
18160
18161         if (adj == ProcessList.SERVICE_ADJ) {
18162             if (doingAll) {
18163                 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
18164                 mNewNumServiceProcs++;
18165                 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
18166                 if (!app.serviceb) {
18167                     // This service isn't far enough down on the LRU list to
18168                     // normally be a B service, but if we are low on RAM and it
18169                     // is large we want to force it down since we would prefer to
18170                     // keep launcher over it.
18171                     if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
18172                             && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
18173                         app.serviceHighRam = true;
18174                         app.serviceb = true;
18175                         //Slog.i(TAG, "ADJ " + app + " high ram!");
18176                     } else {
18177                         mNewNumAServiceProcs++;
18178                         //Slog.i(TAG, "ADJ " + app + " not high ram!");
18179                     }
18180                 } else {
18181                     app.serviceHighRam = false;
18182                 }
18183             }
18184             if (app.serviceb) {
18185                 adj = ProcessList.SERVICE_B_ADJ;
18186             }
18187         }
18188
18189         app.curRawAdj = adj;
18190
18191         //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
18192         //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
18193         if (adj > app.maxAdj) {
18194             adj = app.maxAdj;
18195             if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
18196                 schedGroup = Process.THREAD_GROUP_DEFAULT;
18197             }
18198         }
18199
18200         // Do final modification to adj.  Everything we do between here and applying
18201         // the final setAdj must be done in this function, because we will also use
18202         // it when computing the final cached adj later.  Note that we don't need to
18203         // worry about this for max adj above, since max adj will always be used to
18204         // keep it out of the cached vaues.
18205         app.curAdj = app.modifyRawOomAdj(adj);
18206         app.curSchedGroup = schedGroup;
18207         app.curProcState = procState;
18208         app.foregroundActivities = foregroundActivities;
18209
18210         return app.curRawAdj;
18211     }
18212
18213     /**
18214      * Record new PSS sample for a process.
18215      */
18216     void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long now) {
18217         EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024);
18218         proc.lastPssTime = now;
18219         proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
18220         if (DEBUG_PSS) Slog.d(TAG_PSS,
18221                 "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
18222                 + " state=" + ProcessList.makeProcStateString(procState));
18223         if (proc.initialIdlePss == 0) {
18224             proc.initialIdlePss = pss;
18225         }
18226         proc.lastPss = pss;
18227         if (procState >= ActivityManager.PROCESS_STATE_HOME) {
18228             proc.lastCachedPss = pss;
18229         }
18230
18231         final SparseArray<Pair<Long, String>> watchUids
18232                 = mMemWatchProcesses.getMap().get(proc.processName);
18233         Long check = null;
18234         if (watchUids != null) {
18235             Pair<Long, String> val = watchUids.get(proc.uid);
18236             if (val == null) {
18237                 val = watchUids.get(0);
18238             }
18239             if (val != null) {
18240                 check = val.first;
18241             }
18242         }
18243         if (check != null) {
18244             if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
18245                 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
18246                 if (!isDebuggable) {
18247                     if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
18248                         isDebuggable = true;
18249                     }
18250                 }
18251                 if (isDebuggable) {
18252                     Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
18253                     final ProcessRecord myProc = proc;
18254                     final File heapdumpFile = DumpHeapProvider.getJavaFile();
18255                     mMemWatchDumpProcName = proc.processName;
18256                     mMemWatchDumpFile = heapdumpFile.toString();
18257                     mMemWatchDumpPid = proc.pid;
18258                     mMemWatchDumpUid = proc.uid;
18259                     BackgroundThread.getHandler().post(new Runnable() {
18260                         @Override
18261                         public void run() {
18262                             revokeUriPermission(ActivityThread.currentActivityThread()
18263                                             .getApplicationThread(),
18264                                     DumpHeapActivity.JAVA_URI,
18265                                     Intent.FLAG_GRANT_READ_URI_PERMISSION
18266                                             | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
18267                                     UserHandle.myUserId());
18268                             ParcelFileDescriptor fd = null;
18269                             try {
18270                                 heapdumpFile.delete();
18271                                 fd = ParcelFileDescriptor.open(heapdumpFile,
18272                                         ParcelFileDescriptor.MODE_CREATE |
18273                                                 ParcelFileDescriptor.MODE_TRUNCATE |
18274                                                 ParcelFileDescriptor.MODE_WRITE_ONLY |
18275                                                 ParcelFileDescriptor.MODE_APPEND);
18276                                 IApplicationThread thread = myProc.thread;
18277                                 if (thread != null) {
18278                                     try {
18279                                         if (DEBUG_PSS) Slog.d(TAG_PSS,
18280                                                 "Requesting dump heap from "
18281                                                 + myProc + " to " + heapdumpFile);
18282                                         thread.dumpHeap(true, heapdumpFile.toString(), fd);
18283                                     } catch (RemoteException e) {
18284                                     }
18285                                 }
18286                             } catch (FileNotFoundException e) {
18287                                 e.printStackTrace();
18288                             } finally {
18289                                 if (fd != null) {
18290                                     try {
18291                                         fd.close();
18292                                     } catch (IOException e) {
18293                                     }
18294                                 }
18295                             }
18296                         }
18297                     });
18298                 } else {
18299                     Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
18300                             + ", but debugging not enabled");
18301                 }
18302             }
18303         }
18304     }
18305
18306     /**
18307      * Schedule PSS collection of a process.
18308      */
18309     void requestPssLocked(ProcessRecord proc, int procState) {
18310         if (mPendingPssProcesses.contains(proc)) {
18311             return;
18312         }
18313         if (mPendingPssProcesses.size() == 0) {
18314             mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
18315         }
18316         if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
18317         proc.pssProcState = procState;
18318         mPendingPssProcesses.add(proc);
18319     }
18320
18321     /**
18322      * Schedule PSS collection of all processes.
18323      */
18324     void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
18325         if (!always) {
18326             if (now < (mLastFullPssTime +
18327                     (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
18328                 return;
18329             }
18330         }
18331         if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
18332         mLastFullPssTime = now;
18333         mFullPssPending = true;
18334         mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
18335         mPendingPssProcesses.clear();
18336         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
18337             ProcessRecord app = mLruProcesses.get(i);
18338             if (app.thread == null
18339                     || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
18340                 continue;
18341             }
18342             if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
18343                 app.pssProcState = app.setProcState;
18344                 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
18345                         mTestPssMode, isSleeping(), now);
18346                 mPendingPssProcesses.add(app);
18347             }
18348         }
18349         mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
18350     }
18351
18352     public void setTestPssMode(boolean enabled) {
18353         synchronized (this) {
18354             mTestPssMode = enabled;
18355             if (enabled) {
18356                 // Whenever we enable the mode, we want to take a snapshot all of current
18357                 // process mem use.
18358                 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
18359             }
18360         }
18361     }
18362
18363     /**
18364      * Ask a given process to GC right now.
18365      */
18366     final void performAppGcLocked(ProcessRecord app) {
18367         try {
18368             app.lastRequestedGc = SystemClock.uptimeMillis();
18369             if (app.thread != null) {
18370                 if (app.reportLowMemory) {
18371                     app.reportLowMemory = false;
18372                     app.thread.scheduleLowMemory();
18373                 } else {
18374                     app.thread.processInBackground();
18375                 }
18376             }
18377         } catch (Exception e) {
18378             // whatever.
18379         }
18380     }
18381
18382     /**
18383      * Returns true if things are idle enough to perform GCs.
18384      */
18385     private final boolean canGcNowLocked() {
18386         boolean processingBroadcasts = false;
18387         for (BroadcastQueue q : mBroadcastQueues) {
18388             if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
18389                 processingBroadcasts = true;
18390             }
18391         }
18392         return !processingBroadcasts
18393                 && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
18394     }
18395
18396     /**
18397      * Perform GCs on all processes that are waiting for it, but only
18398      * if things are idle.
18399      */
18400     final void performAppGcsLocked() {
18401         final int N = mProcessesToGc.size();
18402         if (N <= 0) {
18403             return;
18404         }
18405         if (canGcNowLocked()) {
18406             while (mProcessesToGc.size() > 0) {
18407                 ProcessRecord proc = mProcessesToGc.remove(0);
18408                 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
18409                     if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
18410                             <= SystemClock.uptimeMillis()) {
18411                         // To avoid spamming the system, we will GC processes one
18412                         // at a time, waiting a few seconds between each.
18413                         performAppGcLocked(proc);
18414                         scheduleAppGcsLocked();
18415                         return;
18416                     } else {
18417                         // It hasn't been long enough since we last GCed this
18418                         // process...  put it in the list to wait for its time.
18419                         addProcessToGcListLocked(proc);
18420                         break;
18421                     }
18422                 }
18423             }
18424
18425             scheduleAppGcsLocked();
18426         }
18427     }
18428
18429     /**
18430      * If all looks good, perform GCs on all processes waiting for them.
18431      */
18432     final void performAppGcsIfAppropriateLocked() {
18433         if (canGcNowLocked()) {
18434             performAppGcsLocked();
18435             return;
18436         }
18437         // Still not idle, wait some more.
18438         scheduleAppGcsLocked();
18439     }
18440
18441     /**
18442      * Schedule the execution of all pending app GCs.
18443      */
18444     final void scheduleAppGcsLocked() {
18445         mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
18446
18447         if (mProcessesToGc.size() > 0) {
18448             // Schedule a GC for the time to the next process.
18449             ProcessRecord proc = mProcessesToGc.get(0);
18450             Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
18451
18452             long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
18453             long now = SystemClock.uptimeMillis();
18454             if (when < (now+GC_TIMEOUT)) {
18455                 when = now + GC_TIMEOUT;
18456             }
18457             mHandler.sendMessageAtTime(msg, when);
18458         }
18459     }
18460
18461     /**
18462      * Add a process to the array of processes waiting to be GCed.  Keeps the
18463      * list in sorted order by the last GC time.  The process can't already be
18464      * on the list.
18465      */
18466     final void addProcessToGcListLocked(ProcessRecord proc) {
18467         boolean added = false;
18468         for (int i=mProcessesToGc.size()-1; i>=0; i--) {
18469             if (mProcessesToGc.get(i).lastRequestedGc <
18470                     proc.lastRequestedGc) {
18471                 added = true;
18472                 mProcessesToGc.add(i+1, proc);
18473                 break;
18474             }
18475         }
18476         if (!added) {
18477             mProcessesToGc.add(0, proc);
18478         }
18479     }
18480
18481     /**
18482      * Set up to ask a process to GC itself.  This will either do it
18483      * immediately, or put it on the list of processes to gc the next
18484      * time things are idle.
18485      */
18486     final void scheduleAppGcLocked(ProcessRecord app) {
18487         long now = SystemClock.uptimeMillis();
18488         if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
18489             return;
18490         }
18491         if (!mProcessesToGc.contains(app)) {
18492             addProcessToGcListLocked(app);
18493             scheduleAppGcsLocked();
18494         }
18495     }
18496
18497     final void checkExcessivePowerUsageLocked(boolean doKills) {
18498         updateCpuStatsNow();
18499
18500         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
18501         boolean doWakeKills = doKills;
18502         boolean doCpuKills = doKills;
18503         if (mLastPowerCheckRealtime == 0) {
18504             doWakeKills = false;
18505         }
18506         if (mLastPowerCheckUptime == 0) {
18507             doCpuKills = false;
18508         }
18509         if (stats.isScreenOn()) {
18510             doWakeKills = false;
18511         }
18512         final long curRealtime = SystemClock.elapsedRealtime();
18513         final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
18514         final long curUptime = SystemClock.uptimeMillis();
18515         final long uptimeSince = curUptime - mLastPowerCheckUptime;
18516         mLastPowerCheckRealtime = curRealtime;
18517         mLastPowerCheckUptime = curUptime;
18518         if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
18519             doWakeKills = false;
18520         }
18521         if (uptimeSince < CPU_MIN_CHECK_DURATION) {
18522             doCpuKills = false;
18523         }
18524         int i = mLruProcesses.size();
18525         while (i > 0) {
18526             i--;
18527             ProcessRecord app = mLruProcesses.get(i);
18528             if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
18529                 long wtime;
18530                 synchronized (stats) {
18531                     wtime = stats.getProcessWakeTime(app.info.uid,
18532                             app.pid, curRealtime);
18533                 }
18534                 long wtimeUsed = wtime - app.lastWakeTime;
18535                 long cputimeUsed = app.curCpuTime - app.lastCpuTime;
18536                 if (DEBUG_POWER) {
18537                     StringBuilder sb = new StringBuilder(128);
18538                     sb.append("Wake for ");
18539                     app.toShortString(sb);
18540                     sb.append(": over ");
18541                     TimeUtils.formatDuration(realtimeSince, sb);
18542                     sb.append(" used ");
18543                     TimeUtils.formatDuration(wtimeUsed, sb);
18544                     sb.append(" (");
18545                     sb.append((wtimeUsed*100)/realtimeSince);
18546                     sb.append("%)");
18547                     Slog.i(TAG_POWER, sb.toString());
18548                     sb.setLength(0);
18549                     sb.append("CPU for ");
18550                     app.toShortString(sb);
18551                     sb.append(": over ");
18552                     TimeUtils.formatDuration(uptimeSince, sb);
18553                     sb.append(" used ");
18554                     TimeUtils.formatDuration(cputimeUsed, sb);
18555                     sb.append(" (");
18556                     sb.append((cputimeUsed*100)/uptimeSince);
18557                     sb.append("%)");
18558                     Slog.i(TAG_POWER, sb.toString());
18559                 }
18560                 // If a process has held a wake lock for more
18561                 // than 50% of the time during this period,
18562                 // that sounds bad.  Kill!
18563                 if (doWakeKills && realtimeSince > 0
18564                         && ((wtimeUsed*100)/realtimeSince) >= 50) {
18565                     synchronized (stats) {
18566                         stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
18567                                 realtimeSince, wtimeUsed);
18568                     }
18569                     app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
18570                     app.baseProcessTracker.reportExcessiveWake(app.pkgList);
18571                 } else if (doCpuKills && uptimeSince > 0
18572                         && ((cputimeUsed*100)/uptimeSince) >= 25) {
18573                     synchronized (stats) {
18574                         stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
18575                                 uptimeSince, cputimeUsed);
18576                     }
18577                     app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
18578                     app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
18579                 } else {
18580                     app.lastWakeTime = wtime;
18581                     app.lastCpuTime = app.curCpuTime;
18582                 }
18583             }
18584         }
18585     }
18586
18587     private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now) {
18588         boolean success = true;
18589
18590         if (app.curRawAdj != app.setRawAdj) {
18591             app.setRawAdj = app.curRawAdj;
18592         }
18593
18594         int changes = 0;
18595
18596         if (app.curAdj != app.setAdj) {
18597             ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
18598             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
18599                     "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
18600                     + app.adjType);
18601             app.setAdj = app.curAdj;
18602         }
18603
18604         if (app.setSchedGroup != app.curSchedGroup) {
18605             app.setSchedGroup = app.curSchedGroup;
18606             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
18607                     "Setting process group of " + app.processName
18608                     + " to " + app.curSchedGroup);
18609             if (app.waitingToKill != null && app.curReceiver == null
18610                     && app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
18611                 app.kill(app.waitingToKill, true);
18612                 success = false;
18613             } else {
18614                 if (true) {
18615                     long oldId = Binder.clearCallingIdentity();
18616                     try {
18617                         Process.setProcessGroup(app.pid, app.curSchedGroup);
18618                     } catch (Exception e) {
18619                         Slog.w(TAG, "Failed setting process group of " + app.pid
18620                                 + " to " + app.curSchedGroup);
18621                         e.printStackTrace();
18622                     } finally {
18623                         Binder.restoreCallingIdentity(oldId);
18624                     }
18625                 } else {
18626                     if (app.thread != null) {
18627                         try {
18628                             app.thread.setSchedulingGroup(app.curSchedGroup);
18629                         } catch (RemoteException e) {
18630                         }
18631                     }
18632                 }
18633                 Process.setSwappiness(app.pid,
18634                         app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
18635             }
18636         }
18637         if (app.repForegroundActivities != app.foregroundActivities) {
18638             app.repForegroundActivities = app.foregroundActivities;
18639             changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
18640         }
18641         if (app.repProcState != app.curProcState) {
18642             app.repProcState = app.curProcState;
18643             changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
18644             if (app.thread != null) {
18645                 try {
18646                     if (false) {
18647                         //RuntimeException h = new RuntimeException("here");
18648                         Slog.i(TAG, "Sending new process state " + app.repProcState
18649                                 + " to " + app /*, h*/);
18650                     }
18651                     app.thread.setProcessState(app.repProcState);
18652                 } catch (RemoteException e) {
18653                 }
18654             }
18655         }
18656         if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
18657                 || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
18658             if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
18659                 // Experimental code to more aggressively collect pss while
18660                 // running test...  the problem is that this tends to collect
18661                 // the data right when a process is transitioning between process
18662                 // states, which well tend to give noisy data.
18663                 long start = SystemClock.uptimeMillis();
18664                 long pss = Debug.getPss(app.pid, mTmpLong, null);
18665                 recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], now);
18666                 mPendingPssProcesses.remove(app);
18667                 Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
18668                         + " to " + app.curProcState + ": "
18669                         + (SystemClock.uptimeMillis()-start) + "ms");
18670             }
18671             app.lastStateTime = now;
18672             app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
18673                     mTestPssMode, isSleeping(), now);
18674             if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
18675                     + ProcessList.makeProcStateString(app.setProcState) + " to "
18676                     + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
18677                     + (app.nextPssTime-now) + ": " + app);
18678         } else {
18679             if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
18680                     && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
18681                     mTestPssMode)))) {
18682                 requestPssLocked(app, app.setProcState);
18683                 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
18684                         mTestPssMode, isSleeping(), now);
18685             } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
18686                     "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
18687         }
18688         if (app.setProcState != app.curProcState) {
18689             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
18690                     "Proc state change of " + app.processName
18691                     + " to " + app.curProcState);
18692             boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
18693             boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
18694             if (setImportant && !curImportant) {
18695                 // This app is no longer something we consider important enough to allow to
18696                 // use arbitrary amounts of battery power.  Note
18697                 // its current wake lock time to later know to kill it if
18698                 // it is not behaving well.
18699                 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
18700                 synchronized (stats) {
18701                     app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
18702                             app.pid, SystemClock.elapsedRealtime());
18703                 }
18704                 app.lastCpuTime = app.curCpuTime;
18705
18706             }
18707             // Inform UsageStats of important process state change
18708             // Must be called before updating setProcState
18709             maybeUpdateUsageStatsLocked(app);
18710
18711             app.setProcState = app.curProcState;
18712             if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
18713                 app.notCachedSinceIdle = false;
18714             }
18715             if (!doingAll) {
18716                 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
18717             } else {
18718                 app.procStateChanged = true;
18719             }
18720         }
18721
18722         if (changes != 0) {
18723             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18724                     "Changes in " + app + ": " + changes);
18725             int i = mPendingProcessChanges.size()-1;
18726             ProcessChangeItem item = null;
18727             while (i >= 0) {
18728                 item = mPendingProcessChanges.get(i);
18729                 if (item.pid == app.pid) {
18730                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18731                             "Re-using existing item: " + item);
18732                     break;
18733                 }
18734                 i--;
18735             }
18736             if (i < 0) {
18737                 // No existing item in pending changes; need a new one.
18738                 final int NA = mAvailProcessChanges.size();
18739                 if (NA > 0) {
18740                     item = mAvailProcessChanges.remove(NA-1);
18741                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18742                             "Retrieving available item: " + item);
18743                 } else {
18744                     item = new ProcessChangeItem();
18745                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18746                             "Allocating new item: " + item);
18747                 }
18748                 item.changes = 0;
18749                 item.pid = app.pid;
18750                 item.uid = app.info.uid;
18751                 if (mPendingProcessChanges.size() == 0) {
18752                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18753                             "*** Enqueueing dispatch processes changed!");
18754                     mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
18755                 }
18756                 mPendingProcessChanges.add(item);
18757             }
18758             item.changes |= changes;
18759             item.processState = app.repProcState;
18760             item.foregroundActivities = app.repForegroundActivities;
18761             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18762                     "Item " + Integer.toHexString(System.identityHashCode(item))
18763                     + " " + app.toShortString() + ": changes=" + item.changes
18764                     + " procState=" + item.processState
18765                     + " foreground=" + item.foregroundActivities
18766                     + " type=" + app.adjType + " source=" + app.adjSource
18767                     + " target=" + app.adjTarget);
18768         }
18769
18770         return success;
18771     }
18772
18773     private final void enqueueUidChangeLocked(UidRecord uidRec, boolean gone) {
18774         if (uidRec.pendingChange == null) {
18775             if (mPendingUidChanges.size() == 0) {
18776                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
18777                         "*** Enqueueing dispatch uid changed!");
18778                 mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_MSG).sendToTarget();
18779             }
18780             final int NA = mAvailUidChanges.size();
18781             if (NA > 0) {
18782                 uidRec.pendingChange = mAvailUidChanges.remove(NA-1);
18783                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
18784                         "Retrieving available item: " + uidRec.pendingChange);
18785             } else {
18786                 uidRec.pendingChange = new UidRecord.ChangeItem();
18787                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
18788                         "Allocating new item: " + uidRec.pendingChange);
18789             }
18790             uidRec.pendingChange.uidRecord = uidRec;
18791             uidRec.pendingChange.uid = uidRec.uid;
18792             mPendingUidChanges.add(uidRec.pendingChange);
18793         }
18794         uidRec.pendingChange.gone = gone;
18795         uidRec.pendingChange.processState = uidRec.setProcState;
18796     }
18797
18798     private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
18799             String authority) {
18800         if (app == null) return;
18801         if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
18802             UserState userState = mStartedUsers.get(app.userId);
18803             if (userState == null) return;
18804             final long now = SystemClock.elapsedRealtime();
18805             Long lastReported = userState.mProviderLastReportedFg.get(authority);
18806             if (lastReported == null || lastReported < now - 60 * 1000L) {
18807                 mUsageStatsService.reportContentProviderUsage(
18808                         authority, providerPkgName, app.userId);
18809                 userState.mProviderLastReportedFg.put(authority, now);
18810             }
18811         }
18812     }
18813
18814     private void maybeUpdateUsageStatsLocked(ProcessRecord app) {
18815         if (DEBUG_USAGE_STATS) {
18816             Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
18817                     + "] state changes: old = " + app.setProcState + ", new = "
18818                     + app.curProcState);
18819         }
18820         if (mUsageStatsService == null) {
18821             return;
18822         }
18823         boolean isInteraction;
18824         // To avoid some abuse patterns, we are going to be careful about what we consider
18825         // to be an app interaction.  Being the top activity doesn't count while the display
18826         // is sleeping, nor do short foreground services.
18827         if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
18828             isInteraction = true;
18829             app.fgInteractionTime = 0;
18830         } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
18831             final long now = SystemClock.elapsedRealtime();
18832             if (app.fgInteractionTime == 0) {
18833                 app.fgInteractionTime = now;
18834                 isInteraction = false;
18835             } else {
18836                 isInteraction = now > app.fgInteractionTime + SERVICE_USAGE_INTERACTION_TIME;
18837             }
18838         } else {
18839             isInteraction = app.curProcState
18840                     <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18841             app.fgInteractionTime = 0;
18842         }
18843         if (isInteraction && !app.reportedInteraction) {
18844             String[] packages = app.getPackageList();
18845             if (packages != null) {
18846                 for (int i = 0; i < packages.length; i++) {
18847                     mUsageStatsService.reportEvent(packages[i], app.userId,
18848                             UsageEvents.Event.SYSTEM_INTERACTION);
18849                 }
18850             }
18851         }
18852         app.reportedInteraction = isInteraction;
18853     }
18854
18855     private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
18856         if (proc.thread != null) {
18857             if (proc.baseProcessTracker != null) {
18858                 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
18859             }
18860             if (proc.repProcState >= 0) {
18861                 mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
18862                         proc.repProcState);
18863             }
18864         }
18865     }
18866
18867     private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
18868             ProcessRecord TOP_APP, boolean doingAll, long now) {
18869         if (app.thread == null) {
18870             return false;
18871         }
18872
18873         computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
18874
18875         return applyOomAdjLocked(app, doingAll, now);
18876     }
18877
18878     final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
18879             boolean oomAdj) {
18880         if (isForeground != proc.foregroundServices) {
18881             proc.foregroundServices = isForeground;
18882             ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
18883                     proc.info.uid);
18884             if (isForeground) {
18885                 if (curProcs == null) {
18886                     curProcs = new ArrayList<ProcessRecord>();
18887                     mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
18888                 }
18889                 if (!curProcs.contains(proc)) {
18890                     curProcs.add(proc);
18891                     mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
18892                             proc.info.packageName, proc.info.uid);
18893                 }
18894             } else {
18895                 if (curProcs != null) {
18896                     if (curProcs.remove(proc)) {
18897                         mBatteryStatsService.noteEvent(
18898                                 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
18899                                 proc.info.packageName, proc.info.uid);
18900                         if (curProcs.size() <= 0) {
18901                             mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
18902                         }
18903                     }
18904                 }
18905             }
18906             if (oomAdj) {
18907                 updateOomAdjLocked();
18908             }
18909         }
18910     }
18911
18912     private final ActivityRecord resumedAppLocked() {
18913         ActivityRecord act = mStackSupervisor.resumedAppLocked();
18914         String pkg;
18915         int uid;
18916         if (act != null) {
18917             pkg = act.packageName;
18918             uid = act.info.applicationInfo.uid;
18919         } else {
18920             pkg = null;
18921             uid = -1;
18922         }
18923         // Has the UID or resumed package name changed?
18924         if (uid != mCurResumedUid || (pkg != mCurResumedPackage
18925                 && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
18926             if (mCurResumedPackage != null) {
18927                 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
18928                         mCurResumedPackage, mCurResumedUid);
18929             }
18930             mCurResumedPackage = pkg;
18931             mCurResumedUid = uid;
18932             if (mCurResumedPackage != null) {
18933                 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
18934                         mCurResumedPackage, mCurResumedUid);
18935             }
18936         }
18937         return act;
18938     }
18939
18940     final boolean updateOomAdjLocked(ProcessRecord app) {
18941         final ActivityRecord TOP_ACT = resumedAppLocked();
18942         final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
18943         final boolean wasCached = app.cached;
18944
18945         mAdjSeq++;
18946
18947         // This is the desired cached adjusment we want to tell it to use.
18948         // If our app is currently cached, we know it, and that is it.  Otherwise,
18949         // we don't know it yet, and it needs to now be cached we will then
18950         // need to do a complete oom adj.
18951         final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
18952                 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
18953         boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
18954                 SystemClock.uptimeMillis());
18955         if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
18956             // Changed to/from cached state, so apps after it in the LRU
18957             // list may also be changed.
18958             updateOomAdjLocked();
18959         }
18960         return success;
18961     }
18962
18963     final void updateOomAdjLocked() {
18964         final ActivityRecord TOP_ACT = resumedAppLocked();
18965         final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
18966         final long now = SystemClock.uptimeMillis();
18967         final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
18968         final int N = mLruProcesses.size();
18969
18970         if (false) {
18971             RuntimeException e = new RuntimeException();
18972             e.fillInStackTrace();
18973             Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
18974         }
18975
18976         // Reset state in all uid records.
18977         for (int i=mActiveUids.size()-1; i>=0; i--) {
18978             final UidRecord uidRec = mActiveUids.valueAt(i);
18979             if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
18980                     "Starting update of " + uidRec);
18981             uidRec.reset();
18982         }
18983
18984         mAdjSeq++;
18985         mNewNumServiceProcs = 0;
18986         mNewNumAServiceProcs = 0;
18987
18988         final int emptyProcessLimit;
18989         final int cachedProcessLimit;
18990         if (mProcessLimit <= 0) {
18991             emptyProcessLimit = cachedProcessLimit = 0;
18992         } else if (mProcessLimit == 1) {
18993             emptyProcessLimit = 1;
18994             cachedProcessLimit = 0;
18995         } else {
18996             emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
18997             cachedProcessLimit = mProcessLimit - emptyProcessLimit;
18998         }
18999
19000         // Let's determine how many processes we have running vs.
19001         // how many slots we have for background processes; we may want
19002         // to put multiple processes in a slot of there are enough of
19003         // them.
19004         int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
19005                 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
19006         int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
19007         if (numEmptyProcs > cachedProcessLimit) {
19008             // If there are more empty processes than our limit on cached
19009             // processes, then use the cached process limit for the factor.
19010             // This ensures that the really old empty processes get pushed
19011             // down to the bottom, so if we are running low on memory we will
19012             // have a better chance at keeping around more cached processes
19013             // instead of a gazillion empty processes.
19014             numEmptyProcs = cachedProcessLimit;
19015         }
19016         int emptyFactor = numEmptyProcs/numSlots;
19017         if (emptyFactor < 1) emptyFactor = 1;
19018         int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
19019         if (cachedFactor < 1) cachedFactor = 1;
19020         int stepCached = 0;
19021         int stepEmpty = 0;
19022         int numCached = 0;
19023         int numEmpty = 0;
19024         int numTrimming = 0;
19025
19026         mNumNonCachedProcs = 0;
19027         mNumCachedHiddenProcs = 0;
19028
19029         // First update the OOM adjustment for each of the
19030         // application processes based on their current state.
19031         int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
19032         int nextCachedAdj = curCachedAdj+1;
19033         int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
19034         int nextEmptyAdj = curEmptyAdj+2;
19035         for (int i=N-1; i>=0; i--) {
19036             ProcessRecord app = mLruProcesses.get(i);
19037             if (!app.killedByAm && app.thread != null) {
19038                 app.procStateChanged = false;
19039                 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
19040
19041                 // If we haven't yet assigned the final cached adj
19042                 // to the process, do that now.
19043                 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
19044                     switch (app.curProcState) {
19045                         case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
19046                         case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
19047                             // This process is a cached process holding activities...
19048                             // assign it the next cached value for that type, and then
19049                             // step that cached level.
19050                             app.curRawAdj = curCachedAdj;
19051                             app.curAdj = app.modifyRawOomAdj(curCachedAdj);
19052                             if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
19053                                     + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
19054                                     + ")");
19055                             if (curCachedAdj != nextCachedAdj) {
19056                                 stepCached++;
19057                                 if (stepCached >= cachedFactor) {
19058                                     stepCached = 0;
19059                                     curCachedAdj = nextCachedAdj;
19060                                     nextCachedAdj += 2;
19061                                     if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
19062                                         nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
19063                                     }
19064                                 }
19065                             }
19066                             break;
19067                         default:
19068                             // For everything else, assign next empty cached process
19069                             // level and bump that up.  Note that this means that
19070                             // long-running services that have dropped down to the
19071                             // cached level will be treated as empty (since their process
19072                             // state is still as a service), which is what we want.
19073                             app.curRawAdj = curEmptyAdj;
19074                             app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
19075                             if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
19076                                     + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
19077                                     + ")");
19078                             if (curEmptyAdj != nextEmptyAdj) {
19079                                 stepEmpty++;
19080                                 if (stepEmpty >= emptyFactor) {
19081                                     stepEmpty = 0;
19082                                     curEmptyAdj = nextEmptyAdj;
19083                                     nextEmptyAdj += 2;
19084                                     if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
19085                                         nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
19086                                     }
19087                                 }
19088                             }
19089                             break;
19090                     }
19091                 }
19092
19093                 applyOomAdjLocked(app, true, now);
19094
19095                 // Count the number of process types.
19096                 switch (app.curProcState) {
19097                     case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
19098                     case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
19099                         mNumCachedHiddenProcs++;
19100                         numCached++;
19101                         if (numCached > cachedProcessLimit) {
19102                             app.kill("cached #" + numCached, true);
19103                         }
19104                         break;
19105                     case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
19106                         if (numEmpty > ProcessList.TRIM_EMPTY_APPS
19107                                 && app.lastActivityTime < oldTime) {
19108                             app.kill("empty for "
19109                                     + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
19110                                     / 1000) + "s", true);
19111                         } else {
19112                             numEmpty++;
19113                             if (numEmpty > emptyProcessLimit) {
19114                                 app.kill("empty #" + numEmpty, true);
19115                             }
19116                         }
19117                         break;
19118                     default:
19119                         mNumNonCachedProcs++;
19120                         break;
19121                 }
19122
19123                 if (app.isolated && app.services.size() <= 0) {
19124                     // If this is an isolated process, and there are no
19125                     // services running in it, then the process is no longer
19126                     // needed.  We agressively kill these because we can by
19127                     // definition not re-use the same process again, and it is
19128                     // good to avoid having whatever code was running in them
19129                     // left sitting around after no longer needed.
19130                     app.kill("isolated not needed", true);
19131                 } else {
19132                     // Keeping this process, update its uid.
19133                     final UidRecord uidRec = app.uidRecord;
19134                     if (uidRec != null && uidRec.curProcState > app.curProcState) {
19135                         uidRec.curProcState = app.curProcState;
19136                     }
19137                 }
19138
19139                 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
19140                         && !app.killedByAm) {
19141                     numTrimming++;
19142                 }
19143             }
19144         }
19145
19146         mNumServiceProcs = mNewNumServiceProcs;
19147
19148         // Now determine the memory trimming level of background processes.
19149         // Unfortunately we need to start at the back of the list to do this
19150         // properly.  We only do this if the number of background apps we
19151         // are managing to keep around is less than half the maximum we desire;
19152         // if we are keeping a good number around, we'll let them use whatever
19153         // memory they want.
19154         final int numCachedAndEmpty = numCached + numEmpty;
19155         int memFactor;
19156         if (numCached <= ProcessList.TRIM_CACHED_APPS
19157                 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
19158             if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
19159                 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
19160             } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
19161                 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
19162             } else {
19163                 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
19164             }
19165         } else {
19166             memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
19167         }
19168         // We always allow the memory level to go up (better).  We only allow it to go
19169         // down if we are in a state where that is allowed, *and* the total number of processes
19170         // has gone down since last time.
19171         if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
19172                 + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
19173                 + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
19174         if (memFactor > mLastMemoryLevel) {
19175             if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
19176                 memFactor = mLastMemoryLevel;
19177                 if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
19178             }
19179         }
19180         mLastMemoryLevel = memFactor;
19181         mLastNumProcesses = mLruProcesses.size();
19182         boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
19183         final int trackerMemFactor = mProcessStats.getMemFactorLocked();
19184         if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
19185             if (mLowRamStartTime == 0) {
19186                 mLowRamStartTime = now;
19187             }
19188             int step = 0;
19189             int fgTrimLevel;
19190             switch (memFactor) {
19191                 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
19192                     fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
19193                     break;
19194                 case ProcessStats.ADJ_MEM_FACTOR_LOW:
19195                     fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
19196                     break;
19197                 default:
19198                     fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
19199                     break;
19200             }
19201             int factor = numTrimming/3;
19202             int minFactor = 2;
19203             if (mHomeProcess != null) minFactor++;
19204             if (mPreviousProcess != null) minFactor++;
19205             if (factor < minFactor) factor = minFactor;
19206             int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
19207             for (int i=N-1; i>=0; i--) {
19208                 ProcessRecord app = mLruProcesses.get(i);
19209                 if (allChanged || app.procStateChanged) {
19210                     setProcessTrackerStateLocked(app, trackerMemFactor, now);
19211                     app.procStateChanged = false;
19212                 }
19213                 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
19214                         && !app.killedByAm) {
19215                     if (app.trimMemoryLevel < curLevel && app.thread != null) {
19216                         try {
19217                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19218                                     "Trimming memory of " + app.processName + " to " + curLevel);
19219                             app.thread.scheduleTrimMemory(curLevel);
19220                         } catch (RemoteException e) {
19221                         }
19222                         if (false) {
19223                             // For now we won't do this; our memory trimming seems
19224                             // to be good enough at this point that destroying
19225                             // activities causes more harm than good.
19226                             if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
19227                                     && app != mHomeProcess && app != mPreviousProcess) {
19228                                 // Need to do this on its own message because the stack may not
19229                                 // be in a consistent state at this point.
19230                                 // For these apps we will also finish their activities
19231                                 // to help them free memory.
19232                                 mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
19233                             }
19234                         }
19235                     }
19236                     app.trimMemoryLevel = curLevel;
19237                     step++;
19238                     if (step >= factor) {
19239                         step = 0;
19240                         switch (curLevel) {
19241                             case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
19242                                 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
19243                                 break;
19244                             case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
19245                                 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
19246                                 break;
19247                         }
19248                     }
19249                 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
19250                     if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
19251                             && app.thread != null) {
19252                         try {
19253                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19254                                     "Trimming memory of heavy-weight " + app.processName
19255                                     + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
19256                             app.thread.scheduleTrimMemory(
19257                                     ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
19258                         } catch (RemoteException e) {
19259                         }
19260                     }
19261                     app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
19262                 } else {
19263                     if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
19264                             || app.systemNoUi) && app.pendingUiClean) {
19265                         // If this application is now in the background and it
19266                         // had done UI, then give it the special trim level to
19267                         // have it free UI resources.
19268                         final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
19269                         if (app.trimMemoryLevel < level && app.thread != null) {
19270                             try {
19271                                 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19272                                         "Trimming memory of bg-ui " + app.processName
19273                                         + " to " + level);
19274                                 app.thread.scheduleTrimMemory(level);
19275                             } catch (RemoteException e) {
19276                             }
19277                         }
19278                         app.pendingUiClean = false;
19279                     }
19280                     if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
19281                         try {
19282                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19283                                     "Trimming memory of fg " + app.processName
19284                                     + " to " + fgTrimLevel);
19285                             app.thread.scheduleTrimMemory(fgTrimLevel);
19286                         } catch (RemoteException e) {
19287                         }
19288                     }
19289                     app.trimMemoryLevel = fgTrimLevel;
19290                 }
19291             }
19292         } else {
19293             if (mLowRamStartTime != 0) {
19294                 mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
19295                 mLowRamStartTime = 0;
19296             }
19297             for (int i=N-1; i>=0; i--) {
19298                 ProcessRecord app = mLruProcesses.get(i);
19299                 if (allChanged || app.procStateChanged) {
19300                     setProcessTrackerStateLocked(app, trackerMemFactor, now);
19301                     app.procStateChanged = false;
19302                 }
19303                 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
19304                         || app.systemNoUi) && app.pendingUiClean) {
19305                     if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
19306                             && app.thread != null) {
19307                         try {
19308                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19309                                     "Trimming memory of ui hidden " + app.processName
19310                                     + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
19311                             app.thread.scheduleTrimMemory(
19312                                     ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
19313                         } catch (RemoteException e) {
19314                         }
19315                     }
19316                     app.pendingUiClean = false;
19317                 }
19318                 app.trimMemoryLevel = 0;
19319             }
19320         }
19321
19322         if (mAlwaysFinishActivities) {
19323             // Need to do this on its own message because the stack may not
19324             // be in a consistent state at this point.
19325             mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
19326         }
19327
19328         if (allChanged) {
19329             requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
19330         }
19331
19332         // Update from any uid changes.
19333         for (int i=mActiveUids.size()-1; i>=0; i--) {
19334             final UidRecord uidRec = mActiveUids.valueAt(i);
19335             if (uidRec.setProcState != uidRec.curProcState) {
19336                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19337                         "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
19338                         + " to " + uidRec.curProcState);
19339                 uidRec.setProcState = uidRec.curProcState;
19340                 enqueueUidChangeLocked(uidRec, false);
19341             }
19342         }
19343
19344         if (mProcessStats.shouldWriteNowLocked(now)) {
19345             mHandler.post(new Runnable() {
19346                 @Override public void run() {
19347                     synchronized (ActivityManagerService.this) {
19348                         mProcessStats.writeStateAsyncLocked();
19349                     }
19350                 }
19351             });
19352         }
19353
19354         if (DEBUG_OOM_ADJ) {
19355             final long duration = SystemClock.uptimeMillis() - now;
19356             if (false) {
19357                 Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
19358                         new RuntimeException("here").fillInStackTrace());
19359             } else {
19360                 Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
19361             }
19362         }
19363     }
19364
19365     final void trimApplications() {
19366         synchronized (this) {
19367             int i;
19368
19369             // First remove any unused application processes whose package
19370             // has been removed.
19371             for (i=mRemovedProcesses.size()-1; i>=0; i--) {
19372                 final ProcessRecord app = mRemovedProcesses.get(i);
19373                 if (app.activities.size() == 0
19374                         && app.curReceiver == null && app.services.size() == 0) {
19375                     Slog.i(
19376                         TAG, "Exiting empty application process "
19377                         + app.processName + " ("
19378                         + (app.thread != null ? app.thread.asBinder() : null)
19379                         + ")\n");
19380                     if (app.pid > 0 && app.pid != MY_PID) {
19381                         app.kill("empty", false);
19382                     } else {
19383                         try {
19384                             app.thread.scheduleExit();
19385                         } catch (Exception e) {
19386                             // Ignore exceptions.
19387                         }
19388                     }
19389                     cleanUpApplicationRecordLocked(app, false, true, -1);
19390                     mRemovedProcesses.remove(i);
19391
19392                     if (app.persistent) {
19393                         addAppLocked(app.info, false, null /* ABI override */);
19394                     }
19395                 }
19396             }
19397
19398             // Now update the oom adj for all processes.
19399             updateOomAdjLocked();
19400         }
19401     }
19402
19403     /** This method sends the specified signal to each of the persistent apps */
19404     public void signalPersistentProcesses(int sig) throws RemoteException {
19405         if (sig != Process.SIGNAL_USR1) {
19406             throw new SecurityException("Only SIGNAL_USR1 is allowed");
19407         }
19408
19409         synchronized (this) {
19410             if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
19411                     != PackageManager.PERMISSION_GRANTED) {
19412                 throw new SecurityException("Requires permission "
19413                         + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
19414             }
19415
19416             for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
19417                 ProcessRecord r = mLruProcesses.get(i);
19418                 if (r.thread != null && r.persistent) {
19419                     Process.sendSignal(r.pid, sig);
19420                 }
19421             }
19422         }
19423     }
19424
19425     private void stopProfilerLocked(ProcessRecord proc, int profileType) {
19426         if (proc == null || proc == mProfileProc) {
19427             proc = mProfileProc;
19428             profileType = mProfileType;
19429             clearProfilerLocked();
19430         }
19431         if (proc == null) {
19432             return;
19433         }
19434         try {
19435             proc.thread.profilerControl(false, null, profileType);
19436         } catch (RemoteException e) {
19437             throw new IllegalStateException("Process disappeared");
19438         }
19439     }
19440
19441     private void clearProfilerLocked() {
19442         if (mProfileFd != null) {
19443             try {
19444                 mProfileFd.close();
19445             } catch (IOException e) {
19446             }
19447         }
19448         mProfileApp = null;
19449         mProfileProc = null;
19450         mProfileFile = null;
19451         mProfileType = 0;
19452         mAutoStopProfiler = false;
19453         mSamplingInterval = 0;
19454     }
19455
19456     public boolean profileControl(String process, int userId, boolean start,
19457             ProfilerInfo profilerInfo, int profileType) throws RemoteException {
19458
19459         try {
19460             synchronized (this) {
19461                 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
19462                 // its own permission.
19463                 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
19464                         != PackageManager.PERMISSION_GRANTED) {
19465                     throw new SecurityException("Requires permission "
19466                             + android.Manifest.permission.SET_ACTIVITY_WATCHER);
19467                 }
19468
19469                 if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
19470                     throw new IllegalArgumentException("null profile info or fd");
19471                 }
19472
19473                 ProcessRecord proc = null;
19474                 if (process != null) {
19475                     proc = findProcessLocked(process, userId, "profileControl");
19476                 }
19477
19478                 if (start && (proc == null || proc.thread == null)) {
19479                     throw new IllegalArgumentException("Unknown process: " + process);
19480                 }
19481
19482                 if (start) {
19483                     stopProfilerLocked(null, 0);
19484                     setProfileApp(proc.info, proc.processName, profilerInfo);
19485                     mProfileProc = proc;
19486                     mProfileType = profileType;
19487                     ParcelFileDescriptor fd = profilerInfo.profileFd;
19488                     try {
19489                         fd = fd.dup();
19490                     } catch (IOException e) {
19491                         fd = null;
19492                     }
19493                     profilerInfo.profileFd = fd;
19494                     proc.thread.profilerControl(start, profilerInfo, profileType);
19495                     fd = null;
19496                     mProfileFd = null;
19497                 } else {
19498                     stopProfilerLocked(proc, profileType);
19499                     if (profilerInfo != null && profilerInfo.profileFd != null) {
19500                         try {
19501                             profilerInfo.profileFd.close();
19502                         } catch (IOException e) {
19503                         }
19504                     }
19505                 }
19506
19507                 return true;
19508             }
19509         } catch (RemoteException e) {
19510             throw new IllegalStateException("Process disappeared");
19511         } finally {
19512             if (profilerInfo != null && profilerInfo.profileFd != null) {
19513                 try {
19514                     profilerInfo.profileFd.close();
19515                 } catch (IOException e) {
19516                 }
19517             }
19518         }
19519     }
19520
19521     private ProcessRecord findProcessLocked(String process, int userId, String callName) {
19522         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
19523                 userId, true, ALLOW_FULL_ONLY, callName, null);
19524         ProcessRecord proc = null;
19525         try {
19526             int pid = Integer.parseInt(process);
19527             synchronized (mPidsSelfLocked) {
19528                 proc = mPidsSelfLocked.get(pid);
19529             }
19530         } catch (NumberFormatException e) {
19531         }
19532
19533         if (proc == null) {
19534             ArrayMap<String, SparseArray<ProcessRecord>> all
19535                     = mProcessNames.getMap();
19536             SparseArray<ProcessRecord> procs = all.get(process);
19537             if (procs != null && procs.size() > 0) {
19538                 proc = procs.valueAt(0);
19539                 if (userId != UserHandle.USER_ALL && proc.userId != userId) {
19540                     for (int i=1; i<procs.size(); i++) {
19541                         ProcessRecord thisProc = procs.valueAt(i);
19542                         if (thisProc.userId == userId) {
19543                             proc = thisProc;
19544                             break;
19545                         }
19546                     }
19547                 }
19548             }
19549         }
19550
19551         return proc;
19552     }
19553
19554     public boolean dumpHeap(String process, int userId, boolean managed,
19555             String path, ParcelFileDescriptor fd) throws RemoteException {
19556
19557         try {
19558             synchronized (this) {
19559                 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
19560                 // its own permission (same as profileControl).
19561                 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
19562                         != PackageManager.PERMISSION_GRANTED) {
19563                     throw new SecurityException("Requires permission "
19564                             + android.Manifest.permission.SET_ACTIVITY_WATCHER);
19565                 }
19566
19567                 if (fd == null) {
19568                     throw new IllegalArgumentException("null fd");
19569                 }
19570
19571                 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
19572                 if (proc == null || proc.thread == null) {
19573                     throw new IllegalArgumentException("Unknown process: " + process);
19574                 }
19575
19576                 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
19577                 if (!isDebuggable) {
19578                     if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
19579                         throw new SecurityException("Process not debuggable: " + proc);
19580                     }
19581                 }
19582
19583                 proc.thread.dumpHeap(managed, path, fd);
19584                 fd = null;
19585                 return true;
19586             }
19587         } catch (RemoteException e) {
19588             throw new IllegalStateException("Process disappeared");
19589         } finally {
19590             if (fd != null) {
19591                 try {
19592                     fd.close();
19593                 } catch (IOException e) {
19594                 }
19595             }
19596         }
19597     }
19598
19599     @Override
19600     public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
19601             String reportPackage) {
19602         if (processName != null) {
19603             enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
19604                     "setDumpHeapDebugLimit()");
19605         } else {
19606             synchronized (mPidsSelfLocked) {
19607                 ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
19608                 if (proc == null) {
19609                     throw new SecurityException("No process found for calling pid "
19610                             + Binder.getCallingPid());
19611                 }
19612                 if (!Build.IS_DEBUGGABLE
19613                         && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
19614                     throw new SecurityException("Not running a debuggable build");
19615                 }
19616                 processName = proc.processName;
19617                 uid = proc.uid;
19618                 if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
19619                     throw new SecurityException("Package " + reportPackage + " is not running in "
19620                             + proc);
19621                 }
19622             }
19623         }
19624         synchronized (this) {
19625             if (maxMemSize > 0) {
19626                 mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
19627             } else {
19628                 if (uid != 0) {
19629                     mMemWatchProcesses.remove(processName, uid);
19630                 } else {
19631                     mMemWatchProcesses.getMap().remove(processName);
19632                 }
19633             }
19634         }
19635     }
19636
19637     @Override
19638     public void dumpHeapFinished(String path) {
19639         synchronized (this) {
19640             if (Binder.getCallingPid() != mMemWatchDumpPid) {
19641                 Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
19642                         + " does not match last pid " + mMemWatchDumpPid);
19643                 return;
19644             }
19645             if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
19646                 Slog.w(TAG, "dumpHeapFinished: Calling path " + path
19647                         + " does not match last path " + mMemWatchDumpFile);
19648                 return;
19649             }
19650             if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
19651             mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
19652         }
19653     }
19654
19655     /** In this method we try to acquire our lock to make sure that we have not deadlocked */
19656     public void monitor() {
19657         synchronized (this) { }
19658     }
19659
19660     void onCoreSettingsChange(Bundle settings) {
19661         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
19662             ProcessRecord processRecord = mLruProcesses.get(i);
19663             try {
19664                 if (processRecord.thread != null) {
19665                     processRecord.thread.setCoreSettings(settings);
19666                 }
19667             } catch (RemoteException re) {
19668                 /* ignore */
19669             }
19670         }
19671     }
19672
19673     // Multi-user methods
19674
19675     /**
19676      * Start user, if its not already running, but don't bring it to foreground.
19677      */
19678     @Override
19679     public boolean startUserInBackground(final int userId) {
19680         return startUser(userId, /* foreground */ false);
19681     }
19682
19683     /**
19684      * Start user, if its not already running, and bring it to foreground.
19685      */
19686     boolean startUserInForeground(final int userId, Dialog dlg) {
19687         boolean result = startUser(userId, /* foreground */ true);
19688         dlg.dismiss();
19689         return result;
19690     }
19691
19692     /**
19693      * Refreshes the list of users related to the current user when either a
19694      * user switch happens or when a new related user is started in the
19695      * background.
19696      */
19697     private void updateCurrentProfileIdsLocked() {
19698         final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
19699                 mCurrentUserId, false /* enabledOnly */);
19700         int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
19701         for (int i = 0; i < currentProfileIds.length; i++) {
19702             currentProfileIds[i] = profiles.get(i).id;
19703         }
19704         mCurrentProfileIds = currentProfileIds;
19705
19706         synchronized (mUserProfileGroupIdsSelfLocked) {
19707             mUserProfileGroupIdsSelfLocked.clear();
19708             final List<UserInfo> users = getUserManagerLocked().getUsers(false);
19709             for (int i = 0; i < users.size(); i++) {
19710                 UserInfo user = users.get(i);
19711                 if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
19712                     mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
19713                 }
19714             }
19715         }
19716     }
19717
19718     private Set<Integer> getProfileIdsLocked(int userId) {
19719         Set<Integer> userIds = new HashSet<Integer>();
19720         final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
19721                 userId, false /* enabledOnly */);
19722         for (UserInfo user : profiles) {
19723             userIds.add(Integer.valueOf(user.id));
19724         }
19725         return userIds;
19726     }
19727
19728     @Override
19729     public boolean switchUser(final int userId) {
19730         enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
19731         String userName;
19732         synchronized (this) {
19733             UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
19734             if (userInfo == null) {
19735                 Slog.w(TAG, "No user info for user #" + userId);
19736                 return false;
19737             }
19738             if (userInfo.isManagedProfile()) {
19739                 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
19740                 return false;
19741             }
19742             userName = userInfo.name;
19743             mTargetUserId = userId;
19744         }
19745         mUiHandler.removeMessages(START_USER_SWITCH_MSG);
19746         mUiHandler.sendMessage(mUiHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName));
19747         return true;
19748     }
19749
19750     private void showUserSwitchDialog(int userId, String userName) {
19751         // The dialog will show and then initiate the user switch by calling startUserInForeground
19752         Dialog d = new UserSwitchingDialog(this, mContext, userId, userName,
19753                 true /* above system */);
19754         d.show();
19755     }
19756
19757     private boolean startUser(final int userId, final boolean foreground) {
19758         if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
19759                 != PackageManager.PERMISSION_GRANTED) {
19760             String msg = "Permission Denial: switchUser() from pid="
19761                     + Binder.getCallingPid()
19762                     + ", uid=" + Binder.getCallingUid()
19763                     + " requires " + INTERACT_ACROSS_USERS_FULL;
19764             Slog.w(TAG, msg);
19765             throw new SecurityException(msg);
19766         }
19767
19768         if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
19769
19770         final long ident = Binder.clearCallingIdentity();
19771         try {
19772             synchronized (this) {
19773                 final int oldUserId = mCurrentUserId;
19774                 if (oldUserId == userId) {
19775                     return true;
19776                 }
19777
19778                 mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
19779                         "startUser", false);
19780
19781                 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
19782                 if (userInfo == null) {
19783                     Slog.w(TAG, "No user info for user #" + userId);
19784                     return false;
19785                 }
19786                 if (foreground && userInfo.isManagedProfile()) {
19787                     Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
19788                     return false;
19789                 }
19790
19791                 if (foreground) {
19792                     mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
19793                             R.anim.screen_user_enter);
19794                 }
19795
19796                 boolean needStart = false;
19797
19798                 // If the user we are switching to is not currently started, then
19799                 // we need to start it now.
19800                 if (mStartedUsers.get(userId) == null) {
19801                     mStartedUsers.put(userId, new UserState(new UserHandle(userId), false));
19802                     updateStartedUserArrayLocked();
19803                     needStart = true;
19804                 }
19805
19806                 final Integer userIdInt = Integer.valueOf(userId);
19807                 mUserLru.remove(userIdInt);
19808                 mUserLru.add(userIdInt);
19809
19810                 if (foreground) {
19811                     mCurrentUserId = userId;
19812                     mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up
19813                     updateCurrentProfileIdsLocked();
19814                     mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
19815                     // Once the internal notion of the active user has switched, we lock the device
19816                     // with the option to show the user switcher on the keyguard.
19817                     mWindowManager.lockNow(null);
19818                 } else {
19819                     final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
19820                     updateCurrentProfileIdsLocked();
19821                     mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
19822                     mUserLru.remove(currentUserIdInt);
19823                     mUserLru.add(currentUserIdInt);
19824                 }
19825
19826                 final UserState uss = mStartedUsers.get(userId);
19827
19828                 // Make sure user is in the started state.  If it is currently
19829                 // stopping, we need to knock that off.
19830                 if (uss.mState == UserState.STATE_STOPPING) {
19831                     // If we are stopping, we haven't sent ACTION_SHUTDOWN,
19832                     // so we can just fairly silently bring the user back from
19833                     // the almost-dead.
19834                     uss.mState = UserState.STATE_RUNNING;
19835                     updateStartedUserArrayLocked();
19836                     needStart = true;
19837                 } else if (uss.mState == UserState.STATE_SHUTDOWN) {
19838                     // This means ACTION_SHUTDOWN has been sent, so we will
19839                     // need to treat this as a new boot of the user.
19840                     uss.mState = UserState.STATE_BOOTING;
19841                     updateStartedUserArrayLocked();
19842                     needStart = true;
19843                 }
19844
19845                 if (uss.mState == UserState.STATE_BOOTING) {
19846                     // Booting up a new user, need to tell system services about it.
19847                     // Note that this is on the same handler as scheduling of broadcasts,
19848                     // which is important because it needs to go first.
19849                     mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
19850                 }
19851
19852                 if (foreground) {
19853                     mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
19854                             oldUserId));
19855                     mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
19856                     mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
19857                     mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
19858                             oldUserId, userId, uss));
19859                     mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
19860                             oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
19861                 }
19862
19863                 if (needStart) {
19864                     // Send USER_STARTED broadcast
19865                     Intent intent = new Intent(Intent.ACTION_USER_STARTED);
19866                     intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
19867                             | Intent.FLAG_RECEIVER_FOREGROUND);
19868                     intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
19869                     broadcastIntentLocked(null, null, intent,
19870                             null, null, 0, null, null, null, AppOpsManager.OP_NONE,
19871                             null, false, false, MY_PID, Process.SYSTEM_UID, userId);
19872                 }
19873
19874                 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
19875                     if (userId != UserHandle.USER_OWNER) {
19876                         Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
19877                         intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
19878                         broadcastIntentLocked(null, null, intent, null,
19879                                 new IIntentReceiver.Stub() {
19880                                     public void performReceive(Intent intent, int resultCode,
19881                                             String data, Bundle extras, boolean ordered,
19882                                             boolean sticky, int sendingUser) {
19883                                         onUserInitialized(uss, foreground, oldUserId, userId);
19884                                     }
19885                                 }, 0, null, null, null, AppOpsManager.OP_NONE,
19886                                 null, true, false, MY_PID, Process.SYSTEM_UID, userId);
19887                         uss.initializing = true;
19888                     } else {
19889                         getUserManagerLocked().makeInitialized(userInfo.id);
19890                     }
19891                 }
19892
19893                 if (foreground) {
19894                     if (!uss.initializing) {
19895                         moveUserToForeground(uss, oldUserId, userId);
19896                     }
19897                 } else {
19898                     mStackSupervisor.startBackgroundUserLocked(userId, uss);
19899                 }
19900
19901                 if (needStart) {
19902                     Intent intent = new Intent(Intent.ACTION_USER_STARTING);
19903                     intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19904                     intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
19905                     broadcastIntentLocked(null, null, intent,
19906                             null, new IIntentReceiver.Stub() {
19907                                 @Override
19908                                 public void performReceive(Intent intent, int resultCode,
19909                                         String data, Bundle extras, boolean ordered, boolean sticky,
19910                                         int sendingUser) throws RemoteException {
19911                                 }
19912                             }, 0, null, null,
19913                             new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
19914                             null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
19915                 }
19916             }
19917         } finally {
19918             Binder.restoreCallingIdentity(ident);
19919         }
19920
19921         return true;
19922     }
19923
19924     void dispatchForegroundProfileChanged(int userId) {
19925         final int N = mUserSwitchObservers.beginBroadcast();
19926         for (int i = 0; i < N; i++) {
19927             try {
19928                 mUserSwitchObservers.getBroadcastItem(i).onForegroundProfileSwitch(userId);
19929             } catch (RemoteException e) {
19930                 // Ignore
19931             }
19932         }
19933         mUserSwitchObservers.finishBroadcast();
19934     }
19935
19936     void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
19937         long ident = Binder.clearCallingIdentity();
19938         try {
19939             Intent intent;
19940             if (oldUserId >= 0) {
19941                 // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
19942                 List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
19943                 int count = profiles.size();
19944                 for (int i = 0; i < count; i++) {
19945                     int profileUserId = profiles.get(i).id;
19946                     intent = new Intent(Intent.ACTION_USER_BACKGROUND);
19947                     intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
19948                             | Intent.FLAG_RECEIVER_FOREGROUND);
19949                     intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
19950                     broadcastIntentLocked(null, null, intent,
19951                             null, null, 0, null, null, null, AppOpsManager.OP_NONE,
19952                             null, false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
19953                 }
19954             }
19955             if (newUserId >= 0) {
19956                 // Send USER_FOREGROUND broadcast to all profiles of the incoming user
19957                 List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
19958                 int count = profiles.size();
19959                 for (int i = 0; i < count; i++) {
19960                     int profileUserId = profiles.get(i).id;
19961                     intent = new Intent(Intent.ACTION_USER_FOREGROUND);
19962                     intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
19963                             | Intent.FLAG_RECEIVER_FOREGROUND);
19964                     intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
19965                     broadcastIntentLocked(null, null, intent,
19966                             null, null, 0, null, null, null, AppOpsManager.OP_NONE,
19967                             null, false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
19968                 }
19969                 intent = new Intent(Intent.ACTION_USER_SWITCHED);
19970                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
19971                         | Intent.FLAG_RECEIVER_FOREGROUND);
19972                 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
19973                 broadcastIntentLocked(null, null, intent,
19974                         null, null, 0, null, null,
19975                         new String[] {android.Manifest.permission.MANAGE_USERS},
19976                         AppOpsManager.OP_NONE, null, false, false, MY_PID, Process.SYSTEM_UID,
19977                         UserHandle.USER_ALL);
19978             }
19979         } finally {
19980             Binder.restoreCallingIdentity(ident);
19981         }
19982     }
19983
19984     void dispatchUserSwitch(final UserState uss, final int oldUserId,
19985             final int newUserId) {
19986         final int N = mUserSwitchObservers.beginBroadcast();
19987         if (N > 0) {
19988             final IRemoteCallback callback = new IRemoteCallback.Stub() {
19989                 int mCount = 0;
19990                 @Override
19991                 public void sendResult(Bundle data) throws RemoteException {
19992                     synchronized (ActivityManagerService.this) {
19993                         if (mCurUserSwitchCallback == this) {
19994                             mCount++;
19995                             if (mCount == N) {
19996                                 sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
19997                             }
19998                         }
19999                     }
20000                 }
20001             };
20002             synchronized (this) {
20003                 uss.switching = true;
20004                 mCurUserSwitchCallback = callback;
20005             }
20006             for (int i=0; i<N; i++) {
20007                 try {
20008                     mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
20009                             newUserId, callback);
20010                 } catch (RemoteException e) {
20011                 }
20012             }
20013         } else {
20014             synchronized (this) {
20015                 sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
20016             }
20017         }
20018         mUserSwitchObservers.finishBroadcast();
20019     }
20020
20021     void timeoutUserSwitch(UserState uss, int oldUserId, int newUserId) {
20022         synchronized (this) {
20023             Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
20024             sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
20025         }
20026     }
20027
20028     void sendContinueUserSwitchLocked(UserState uss, int oldUserId, int newUserId) {
20029         mCurUserSwitchCallback = null;
20030         mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
20031         mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
20032                 oldUserId, newUserId, uss));
20033     }
20034
20035     void onUserInitialized(UserState uss, boolean foreground, int oldUserId, int newUserId) {
20036         synchronized (this) {
20037             if (foreground) {
20038                 moveUserToForeground(uss, oldUserId, newUserId);
20039             }
20040         }
20041
20042         completeSwitchAndInitialize(uss, newUserId, true, false);
20043     }
20044
20045     void moveUserToForeground(UserState uss, int oldUserId, int newUserId) {
20046         boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss);
20047         if (homeInFront) {
20048             startHomeActivityLocked(newUserId, "moveUserToFroreground");
20049         } else {
20050             mStackSupervisor.resumeTopActivitiesLocked();
20051         }
20052         EventLogTags.writeAmSwitchUser(newUserId);
20053         getUserManagerLocked().onUserForeground(newUserId);
20054         sendUserSwitchBroadcastsLocked(oldUserId, newUserId);
20055     }
20056
20057     void continueUserSwitch(UserState uss, int oldUserId, int newUserId) {
20058         completeSwitchAndInitialize(uss, newUserId, false, true);
20059     }
20060
20061     void completeSwitchAndInitialize(UserState uss, int newUserId,
20062             boolean clearInitializing, boolean clearSwitching) {
20063         boolean unfrozen = false;
20064         synchronized (this) {
20065             if (clearInitializing) {
20066                 uss.initializing = false;
20067                 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
20068             }
20069             if (clearSwitching) {
20070                 uss.switching = false;
20071             }
20072             if (!uss.switching && !uss.initializing) {
20073                 mWindowManager.stopFreezingScreen();
20074                 unfrozen = true;
20075             }
20076         }
20077         if (unfrozen) {
20078             mHandler.removeMessages(REPORT_USER_SWITCH_COMPLETE_MSG);
20079             mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_COMPLETE_MSG,
20080                     newUserId, 0));
20081         }
20082         stopGuestUserIfBackground();
20083     }
20084
20085     /** Called on handler thread */
20086     void dispatchUserSwitchComplete(int userId) {
20087         final int observerCount = mUserSwitchObservers.beginBroadcast();
20088         for (int i = 0; i < observerCount; i++) {
20089             try {
20090                 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(userId);
20091             } catch (RemoteException e) {
20092             }
20093         }
20094         mUserSwitchObservers.finishBroadcast();
20095     }
20096
20097     /**
20098      * Stops the guest user if it has gone to the background.
20099      */
20100     private void stopGuestUserIfBackground() {
20101         synchronized (this) {
20102             final int num = mUserLru.size();
20103             for (int i = 0; i < num; i++) {
20104                 Integer oldUserId = mUserLru.get(i);
20105                 UserState oldUss = mStartedUsers.get(oldUserId);
20106                 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId
20107                         || oldUss.mState == UserState.STATE_STOPPING
20108                         || oldUss.mState == UserState.STATE_SHUTDOWN) {
20109                     continue;
20110                 }
20111                 UserInfo userInfo = mUserManager.getUserInfo(oldUserId);
20112                 if (userInfo.isGuest()) {
20113                     // This is a user to be stopped.
20114                     stopUserLocked(oldUserId, null);
20115                     break;
20116                 }
20117             }
20118         }
20119     }
20120
20121     void scheduleStartProfilesLocked() {
20122         if (!mHandler.hasMessages(START_PROFILES_MSG)) {
20123             mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
20124                     DateUtils.SECOND_IN_MILLIS);
20125         }
20126     }
20127
20128     void startProfilesLocked() {
20129         if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
20130         List<UserInfo> profiles = getUserManagerLocked().getProfiles(
20131                 mCurrentUserId, false /* enabledOnly */);
20132         List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
20133         for (UserInfo user : profiles) {
20134             if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
20135                     && user.id != mCurrentUserId) {
20136                 toStart.add(user);
20137             }
20138         }
20139         final int n = toStart.size();
20140         int i = 0;
20141         for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
20142             startUserInBackground(toStart.get(i).id);
20143         }
20144         if (i < n) {
20145             Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
20146         }
20147     }
20148
20149     void finishUserBoot(UserState uss) {
20150         synchronized (this) {
20151             if (uss.mState == UserState.STATE_BOOTING
20152                     && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
20153                 uss.mState = UserState.STATE_RUNNING;
20154                 final int userId = uss.mHandle.getIdentifier();
20155                 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
20156                 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
20157                 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
20158                 broadcastIntentLocked(null, null, intent,
20159                         null, null, 0, null, null,
20160                         new String[] {android.Manifest.permission.RECEIVE_BOOT_COMPLETED},
20161                         AppOpsManager.OP_NONE, null, true, false, MY_PID, Process.SYSTEM_UID,
20162                         userId);
20163             }
20164         }
20165     }
20166
20167     void finishUserSwitch(UserState uss) {
20168         synchronized (this) {
20169             finishUserBoot(uss);
20170
20171             startProfilesLocked();
20172
20173             int num = mUserLru.size();
20174             int i = 0;
20175             while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
20176                 Integer oldUserId = mUserLru.get(i);
20177                 UserState oldUss = mStartedUsers.get(oldUserId);
20178                 if (oldUss == null) {
20179                     // Shouldn't happen, but be sane if it does.
20180                     mUserLru.remove(i);
20181                     num--;
20182                     continue;
20183                 }
20184                 if (oldUss.mState == UserState.STATE_STOPPING
20185                         || oldUss.mState == UserState.STATE_SHUTDOWN) {
20186                     // This user is already stopping, doesn't count.
20187                     num--;
20188                     i++;
20189                     continue;
20190                 }
20191                 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
20192                     // Owner and current can't be stopped, but count as running.
20193                     i++;
20194                     continue;
20195                 }
20196                 // This is a user to be stopped.
20197                 stopUserLocked(oldUserId, null);
20198                 num--;
20199                 i++;
20200             }
20201         }
20202     }
20203
20204     @Override
20205     public int stopUser(final int userId, final IStopUserCallback callback) {
20206         if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
20207                 != PackageManager.PERMISSION_GRANTED) {
20208             String msg = "Permission Denial: switchUser() from pid="
20209                     + Binder.getCallingPid()
20210                     + ", uid=" + Binder.getCallingUid()
20211                     + " requires " + INTERACT_ACROSS_USERS_FULL;
20212             Slog.w(TAG, msg);
20213             throw new SecurityException(msg);
20214         }
20215         if (userId < 0 || userId == UserHandle.USER_OWNER) {
20216             throw new IllegalArgumentException("Can't stop primary user " + userId);
20217         }
20218         enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
20219         synchronized (this) {
20220             return stopUserLocked(userId, callback);
20221         }
20222     }
20223
20224     private int stopUserLocked(final int userId, final IStopUserCallback callback) {
20225         if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
20226         if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) {
20227             return ActivityManager.USER_OP_IS_CURRENT;
20228         }
20229
20230         final UserState uss = mStartedUsers.get(userId);
20231         if (uss == null) {
20232             // User is not started, nothing to do...  but we do need to
20233             // callback if requested.
20234             if (callback != null) {
20235                 mHandler.post(new Runnable() {
20236                     @Override
20237                     public void run() {
20238                         try {
20239                             callback.userStopped(userId);
20240                         } catch (RemoteException e) {
20241                         }
20242                     }
20243                 });
20244             }
20245             return ActivityManager.USER_OP_SUCCESS;
20246         }
20247
20248         if (callback != null) {
20249             uss.mStopCallbacks.add(callback);
20250         }
20251
20252         if (uss.mState != UserState.STATE_STOPPING
20253                 && uss.mState != UserState.STATE_SHUTDOWN) {
20254             uss.mState = UserState.STATE_STOPPING;
20255             updateStartedUserArrayLocked();
20256
20257             long ident = Binder.clearCallingIdentity();
20258             try {
20259                 // We are going to broadcast ACTION_USER_STOPPING and then
20260                 // once that is done send a final ACTION_SHUTDOWN and then
20261                 // stop the user.
20262                 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
20263                 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
20264                 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
20265                 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
20266                 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
20267                 // This is the result receiver for the final shutdown broadcast.
20268                 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
20269                     @Override
20270                     public void performReceive(Intent intent, int resultCode, String data,
20271                             Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
20272                         finishUserStop(uss);
20273                     }
20274                 };
20275                 // This is the result receiver for the initial stopping broadcast.
20276                 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
20277                     @Override
20278                     public void performReceive(Intent intent, int resultCode, String data,
20279                             Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
20280                         // On to the next.
20281                         synchronized (ActivityManagerService.this) {
20282                             if (uss.mState != UserState.STATE_STOPPING) {
20283                                 // Whoops, we are being started back up.  Abort, abort!
20284                                 return;
20285                             }
20286                             uss.mState = UserState.STATE_SHUTDOWN;
20287                         }
20288                         mBatteryStatsService.noteEvent(
20289                                 BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
20290                                 Integer.toString(userId), userId);
20291                         mSystemServiceManager.stopUser(userId);
20292                         broadcastIntentLocked(null, null, shutdownIntent,
20293                                 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
20294                                 null, true, false, MY_PID, Process.SYSTEM_UID, userId);
20295                     }
20296                 };
20297                 // Kick things off.
20298                 broadcastIntentLocked(null, null, stoppingIntent,
20299                         null, stoppingReceiver, 0, null, null,
20300                         new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
20301                         null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
20302             } finally {
20303                 Binder.restoreCallingIdentity(ident);
20304             }
20305         }
20306
20307         return ActivityManager.USER_OP_SUCCESS;
20308     }
20309
20310     void finishUserStop(UserState uss) {
20311         final int userId = uss.mHandle.getIdentifier();
20312         boolean stopped;
20313         ArrayList<IStopUserCallback> callbacks;
20314         synchronized (this) {
20315             callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
20316             if (mStartedUsers.get(userId) != uss) {
20317                 stopped = false;
20318             } else if (uss.mState != UserState.STATE_SHUTDOWN) {
20319                 stopped = false;
20320             } else {
20321                 stopped = true;
20322                 // User can no longer run.
20323                 mStartedUsers.remove(userId);
20324                 mUserLru.remove(Integer.valueOf(userId));
20325                 updateStartedUserArrayLocked();
20326
20327                 // Clean up all state and processes associated with the user.
20328                 // Kill all the processes for the user.
20329                 forceStopUserLocked(userId, "finish user");
20330             }
20331
20332             // Explicitly remove the old information in mRecentTasks.
20333             mRecentTasks.removeTasksForUserLocked(userId);
20334         }
20335
20336         for (int i=0; i<callbacks.size(); i++) {
20337             try {
20338                 if (stopped) callbacks.get(i).userStopped(userId);
20339                 else callbacks.get(i).userStopAborted(userId);
20340             } catch (RemoteException e) {
20341             }
20342         }
20343
20344         if (stopped) {
20345             mSystemServiceManager.cleanupUser(userId);
20346             synchronized (this) {
20347                 mStackSupervisor.removeUserLocked(userId);
20348             }
20349         }
20350     }
20351
20352     @Override
20353     public UserInfo getCurrentUser() {
20354         if ((checkCallingPermission(INTERACT_ACROSS_USERS)
20355                 != PackageManager.PERMISSION_GRANTED) && (
20356                 checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
20357                 != PackageManager.PERMISSION_GRANTED)) {
20358             String msg = "Permission Denial: getCurrentUser() from pid="
20359                     + Binder.getCallingPid()
20360                     + ", uid=" + Binder.getCallingUid()
20361                     + " requires " + INTERACT_ACROSS_USERS;
20362             Slog.w(TAG, msg);
20363             throw new SecurityException(msg);
20364         }
20365         synchronized (this) {
20366             int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
20367             return getUserManagerLocked().getUserInfo(userId);
20368         }
20369     }
20370
20371     int getCurrentUserIdLocked() {
20372         return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
20373     }
20374
20375     @Override
20376     public boolean isUserRunning(int userId, boolean orStopped) {
20377         if (checkCallingPermission(INTERACT_ACROSS_USERS)
20378                 != PackageManager.PERMISSION_GRANTED) {
20379             String msg = "Permission Denial: isUserRunning() from pid="
20380                     + Binder.getCallingPid()
20381                     + ", uid=" + Binder.getCallingUid()
20382                     + " requires " + INTERACT_ACROSS_USERS;
20383             Slog.w(TAG, msg);
20384             throw new SecurityException(msg);
20385         }
20386         synchronized (this) {
20387             return isUserRunningLocked(userId, orStopped);
20388         }
20389     }
20390
20391     boolean isUserRunningLocked(int userId, boolean orStopped) {
20392         UserState state = mStartedUsers.get(userId);
20393         if (state == null) {
20394             return false;
20395         }
20396         if (orStopped) {
20397             return true;
20398         }
20399         return state.mState != UserState.STATE_STOPPING
20400                 && state.mState != UserState.STATE_SHUTDOWN;
20401     }
20402
20403     @Override
20404     public int[] getRunningUserIds() {
20405         if (checkCallingPermission(INTERACT_ACROSS_USERS)
20406                 != PackageManager.PERMISSION_GRANTED) {
20407             String msg = "Permission Denial: isUserRunning() from pid="
20408                     + Binder.getCallingPid()
20409                     + ", uid=" + Binder.getCallingUid()
20410                     + " requires " + INTERACT_ACROSS_USERS;
20411             Slog.w(TAG, msg);
20412             throw new SecurityException(msg);
20413         }
20414         synchronized (this) {
20415             return mStartedUserArray;
20416         }
20417     }
20418
20419     private void updateStartedUserArrayLocked() {
20420         int num = 0;
20421         for (int i=0; i<mStartedUsers.size();  i++) {
20422             UserState uss = mStartedUsers.valueAt(i);
20423             // This list does not include stopping users.
20424             if (uss.mState != UserState.STATE_STOPPING
20425                     && uss.mState != UserState.STATE_SHUTDOWN) {
20426                 num++;
20427             }
20428         }
20429         mStartedUserArray = new int[num];
20430         num = 0;
20431         for (int i=0; i<mStartedUsers.size();  i++) {
20432             UserState uss = mStartedUsers.valueAt(i);
20433             if (uss.mState != UserState.STATE_STOPPING
20434                     && uss.mState != UserState.STATE_SHUTDOWN) {
20435                 mStartedUserArray[num] = mStartedUsers.keyAt(i);
20436                 num++;
20437             }
20438         }
20439     }
20440
20441     @Override
20442     public void registerUserSwitchObserver(IUserSwitchObserver observer) {
20443         if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
20444                 != PackageManager.PERMISSION_GRANTED) {
20445             String msg = "Permission Denial: registerUserSwitchObserver() from pid="
20446                     + Binder.getCallingPid()
20447                     + ", uid=" + Binder.getCallingUid()
20448                     + " requires " + INTERACT_ACROSS_USERS_FULL;
20449             Slog.w(TAG, msg);
20450             throw new SecurityException(msg);
20451         }
20452
20453         mUserSwitchObservers.register(observer);
20454     }
20455
20456     @Override
20457     public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
20458         mUserSwitchObservers.unregister(observer);
20459     }
20460
20461     int[] getUsersLocked() {
20462         UserManagerService ums = getUserManagerLocked();
20463         return ums != null ? ums.getUserIds() : new int[] { 0 };
20464     }
20465
20466     UserManagerService getUserManagerLocked() {
20467         if (mUserManager == null) {
20468             IBinder b = ServiceManager.getService(Context.USER_SERVICE);
20469             mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
20470         }
20471         return mUserManager;
20472     }
20473
20474     private int applyUserId(int uid, int userId) {
20475         return UserHandle.getUid(userId, uid);
20476     }
20477
20478     ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
20479         if (info == null) return null;
20480         ApplicationInfo newInfo = new ApplicationInfo(info);
20481         newInfo.uid = applyUserId(info.uid, userId);
20482         newInfo.dataDir = Environment
20483                 .getDataUserPackageDirectory(info.volumeUuid, userId, info.packageName)
20484                 .getAbsolutePath();
20485         return newInfo;
20486     }
20487
20488     ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
20489         if (aInfo == null
20490                 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
20491             return aInfo;
20492         }
20493
20494         ActivityInfo info = new ActivityInfo(aInfo);
20495         info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
20496         return info;
20497     }
20498
20499     private final class LocalService extends ActivityManagerInternal {
20500         @Override
20501         public void onWakefulnessChanged(int wakefulness) {
20502             ActivityManagerService.this.onWakefulnessChanged(wakefulness);
20503         }
20504
20505         @Override
20506         public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
20507                 String processName, String abiOverride, int uid, Runnable crashHandler) {
20508             return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
20509                     processName, abiOverride, uid, crashHandler);
20510         }
20511
20512         @Override
20513         public SleepToken acquireSleepToken(String tag) {
20514             Preconditions.checkNotNull(tag);
20515
20516             synchronized (ActivityManagerService.this) {
20517                 SleepTokenImpl token = new SleepTokenImpl(tag);
20518                 mSleepTokens.add(token);
20519                 updateSleepIfNeededLocked();
20520                 return token;
20521             }
20522         }
20523
20524         @Override
20525         public ComponentName getHomeActivityForUser(int userId) {
20526             synchronized (ActivityManagerService.this) {
20527                 ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
20528                 return homeActivity == null ? null : homeActivity.realActivity;
20529             }
20530         }
20531     }
20532
20533     private final class SleepTokenImpl extends SleepToken {
20534         private final String mTag;
20535         private final long mAcquireTime;
20536
20537         public SleepTokenImpl(String tag) {
20538             mTag = tag;
20539             mAcquireTime = SystemClock.uptimeMillis();
20540         }
20541
20542         @Override
20543         public void release() {
20544             synchronized (ActivityManagerService.this) {
20545                 if (mSleepTokens.remove(this)) {
20546                     updateSleepIfNeededLocked();
20547                 }
20548             }
20549         }
20550
20551         @Override
20552         public String toString() {
20553             return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
20554         }
20555     }
20556
20557     /**
20558      * An implementation of IAppTask, that allows an app to manage its own tasks via
20559      * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
20560      * only the process that calls getAppTasks() can call the AppTask methods.
20561      */
20562     class AppTaskImpl extends IAppTask.Stub {
20563         private int mTaskId;
20564         private int mCallingUid;
20565
20566         public AppTaskImpl(int taskId, int callingUid) {
20567             mTaskId = taskId;
20568             mCallingUid = callingUid;
20569         }
20570
20571         private void checkCaller() {
20572             if (mCallingUid != Binder.getCallingUid()) {
20573                 throw new SecurityException("Caller " + mCallingUid
20574                         + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
20575             }
20576         }
20577
20578         @Override
20579         public void finishAndRemoveTask() {
20580             checkCaller();
20581
20582             synchronized (ActivityManagerService.this) {
20583                 long origId = Binder.clearCallingIdentity();
20584                 try {
20585                     if (!removeTaskByIdLocked(mTaskId, false)) {
20586                         throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20587                     }
20588                 } finally {
20589                     Binder.restoreCallingIdentity(origId);
20590                 }
20591             }
20592         }
20593
20594         @Override
20595         public ActivityManager.RecentTaskInfo getTaskInfo() {
20596             checkCaller();
20597
20598             synchronized (ActivityManagerService.this) {
20599                 long origId = Binder.clearCallingIdentity();
20600                 try {
20601                     TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
20602                     if (tr == null) {
20603                         throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20604                     }
20605                     return createRecentTaskInfoFromTaskRecord(tr);
20606                 } finally {
20607                     Binder.restoreCallingIdentity(origId);
20608                 }
20609             }
20610         }
20611
20612         @Override
20613         public void moveToFront() {
20614             checkCaller();
20615             // Will bring task to front if it already has a root activity.
20616             startActivityFromRecentsInner(mTaskId, null);
20617         }
20618
20619         @Override
20620         public int startActivity(IBinder whoThread, String callingPackage,
20621                 Intent intent, String resolvedType, Bundle options) {
20622             checkCaller();
20623
20624             int callingUser = UserHandle.getCallingUserId();
20625             TaskRecord tr;
20626             IApplicationThread appThread;
20627             synchronized (ActivityManagerService.this) {
20628                 tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
20629                 if (tr == null) {
20630                     throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20631                 }
20632                 appThread = ApplicationThreadNative.asInterface(whoThread);
20633                 if (appThread == null) {
20634                     throw new IllegalArgumentException("Bad app thread " + appThread);
20635                 }
20636             }
20637             return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent,
20638                     resolvedType, null, null, null, null, 0, 0, null, null,
20639                     null, options, false, callingUser, null, tr);
20640         }
20641
20642         @Override
20643         public void setExcludeFromRecents(boolean exclude) {
20644             checkCaller();
20645
20646             synchronized (ActivityManagerService.this) {
20647                 long origId = Binder.clearCallingIdentity();
20648                 try {
20649                     TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
20650                     if (tr == null) {
20651                         throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20652                     }
20653                     Intent intent = tr.getBaseIntent();
20654                     if (exclude) {
20655                         intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
20656                     } else {
20657                         intent.setFlags(intent.getFlags()
20658                                 & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
20659                     }
20660                 } finally {
20661                     Binder.restoreCallingIdentity(origId);
20662                 }
20663             }
20664         }
20665     }
20666 }