OSDN Git Service

am 971ff47c: am 1b06455e: (-s ours) am 00db0826: am 203b4354: Merge "Revert "[DO...
[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
404     // Delay to disable app launch boost
405     static final int APP_BOOST_MESSAGE_DELAY = 3000;
406     // Lower delay than APP_BOOST_MESSAGE_DELAY to disable the boost
407     static final int APP_BOOST_TIMEOUT = 2500;
408
409     private static native int nativeMigrateToBoost();
410     private static native int nativeMigrateFromBoost();
411     private boolean mIsBoosted = false;
412     private long mBoostStartTime = 0;
413
414     /** All system services */
415     SystemServiceManager mSystemServiceManager;
416
417     private Installer mInstaller;
418
419     /** Run all ActivityStacks through this */
420     ActivityStackSupervisor mStackSupervisor;
421
422     /** Task stack change listeners. */
423     private RemoteCallbackList<ITaskStackListener> mTaskStackListeners =
424             new RemoteCallbackList<ITaskStackListener>();
425
426     public IntentFirewall mIntentFirewall;
427
428     // Whether we should show our dialogs (ANR, crash, etc) or just perform their
429     // default actuion automatically.  Important for devices without direct input
430     // devices.
431     private boolean mShowDialogs = true;
432
433     BroadcastQueue mFgBroadcastQueue;
434     BroadcastQueue mBgBroadcastQueue;
435     // Convenient for easy iteration over the queues. Foreground is first
436     // so that dispatch of foreground broadcasts gets precedence.
437     final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
438
439     BroadcastQueue broadcastQueueForIntent(Intent intent) {
440         final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
441         if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
442                 "Broadcast intent " + intent + " on "
443                 + (isFg ? "foreground" : "background") + " queue");
444         return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
445     }
446
447     /**
448      * Activity we have told the window manager to have key focus.
449      */
450     ActivityRecord mFocusedActivity = null;
451
452     /**
453      * User id of the last activity mFocusedActivity was set to.
454      */
455     private int mLastFocusedUserId;
456
457     /**
458      * If non-null, we are tracking the time the user spends in the currently focused app.
459      */
460     private AppTimeTracker mCurAppTimeTracker;
461
462     /**
463      * List of intents that were used to start the most recent tasks.
464      */
465     private final RecentTasks mRecentTasks;
466
467     /**
468      * For addAppTask: cached of the last activity component that was added.
469      */
470     ComponentName mLastAddedTaskComponent;
471
472     /**
473      * For addAppTask: cached of the last activity uid that was added.
474      */
475     int mLastAddedTaskUid;
476
477     /**
478      * For addAppTask: cached of the last ActivityInfo that was added.
479      */
480     ActivityInfo mLastAddedTaskActivity;
481
482     /**
483      * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId.
484      */
485     SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
486
487     /**
488      * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
489      */
490     String mDeviceOwnerName;
491
492     public class PendingAssistExtras extends Binder implements Runnable {
493         public final ActivityRecord activity;
494         public final Bundle extras;
495         public final Intent intent;
496         public final String hint;
497         public final IResultReceiver receiver;
498         public final int userHandle;
499         public boolean haveResult = false;
500         public Bundle result = null;
501         public AssistStructure structure = null;
502         public AssistContent content = null;
503         public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
504                 String _hint, IResultReceiver _receiver, int _userHandle) {
505             activity = _activity;
506             extras = _extras;
507             intent = _intent;
508             hint = _hint;
509             receiver = _receiver;
510             userHandle = _userHandle;
511         }
512         @Override
513         public void run() {
514             Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
515             synchronized (this) {
516                 haveResult = true;
517                 notifyAll();
518             }
519             pendingAssistExtrasTimedOut(this);
520         }
521     }
522
523     final ArrayList<PendingAssistExtras> mPendingAssistExtras
524             = new ArrayList<PendingAssistExtras>();
525
526     /**
527      * Process management.
528      */
529     final ProcessList mProcessList = new ProcessList();
530
531     /**
532      * All of the applications we currently have running organized by name.
533      * The keys are strings of the application package name (as
534      * returned by the package manager), and the keys are ApplicationRecord
535      * objects.
536      */
537     final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
538
539     /**
540      * Tracking long-term execution of processes to look for abuse and other
541      * bad app behavior.
542      */
543     final ProcessStatsService mProcessStats;
544
545     /**
546      * The currently running isolated processes.
547      */
548     final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
549
550     /**
551      * Counter for assigning isolated process uids, to avoid frequently reusing the
552      * same ones.
553      */
554     int mNextIsolatedProcessUid = 0;
555
556     /**
557      * The currently running heavy-weight process, if any.
558      */
559     ProcessRecord mHeavyWeightProcess = null;
560
561     /**
562      * The last time that various processes have crashed.
563      */
564     final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
565
566     /**
567      * Information about a process that is currently marked as bad.
568      */
569     static final class BadProcessInfo {
570         BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
571             this.time = time;
572             this.shortMsg = shortMsg;
573             this.longMsg = longMsg;
574             this.stack = stack;
575         }
576
577         final long time;
578         final String shortMsg;
579         final String longMsg;
580         final String stack;
581     }
582
583     /**
584      * Set of applications that we consider to be bad, and will reject
585      * incoming broadcasts from (which the user has no control over).
586      * Processes are added to this set when they have crashed twice within
587      * a minimum amount of time; they are removed from it when they are
588      * later restarted (hopefully due to some user action).  The value is the
589      * time it was added to the list.
590      */
591     final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
592
593     /**
594      * All of the processes we currently have running organized by pid.
595      * The keys are the pid running the application.
596      *
597      * <p>NOTE: This object is protected by its own lock, NOT the global
598      * activity manager lock!
599      */
600     final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
601
602     /**
603      * All of the processes that have been forced to be foreground.  The key
604      * is the pid of the caller who requested it (we hold a death
605      * link on it).
606      */
607     abstract class ForegroundToken implements IBinder.DeathRecipient {
608         int pid;
609         IBinder token;
610     }
611     final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
612
613     /**
614      * List of records for processes that someone had tried to start before the
615      * system was ready.  We don't start them at that point, but ensure they
616      * are started by the time booting is complete.
617      */
618     final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
619
620     /**
621      * List of persistent applications that are in the process
622      * of being started.
623      */
624     final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
625
626     /**
627      * Processes that are being forcibly torn down.
628      */
629     final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
630
631     /**
632      * List of running applications, sorted by recent usage.
633      * The first entry in the list is the least recently used.
634      */
635     final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
636
637     /**
638      * Where in mLruProcesses that the processes hosting activities start.
639      */
640     int mLruProcessActivityStart = 0;
641
642     /**
643      * Where in mLruProcesses that the processes hosting services start.
644      * This is after (lower index) than mLruProcessesActivityStart.
645      */
646     int mLruProcessServiceStart = 0;
647
648     /**
649      * List of processes that should gc as soon as things are idle.
650      */
651     final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
652
653     /**
654      * Processes we want to collect PSS data from.
655      */
656     final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
657
658     /**
659      * Last time we requested PSS data of all processes.
660      */
661     long mLastFullPssTime = SystemClock.uptimeMillis();
662
663     /**
664      * If set, the next time we collect PSS data we should do a full collection
665      * with data from native processes and the kernel.
666      */
667     boolean mFullPssPending = false;
668
669     /**
670      * This is the process holding what we currently consider to be
671      * the "home" activity.
672      */
673     ProcessRecord mHomeProcess;
674
675     /**
676      * This is the process holding the activity the user last visited that
677      * is in a different process from the one they are currently in.
678      */
679     ProcessRecord mPreviousProcess;
680
681     /**
682      * The time at which the previous process was last visible.
683      */
684     long mPreviousProcessVisibleTime;
685
686     /**
687      * Track all uids that have actively running processes.
688      */
689     final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
690
691     /**
692      * Which users have been started, so are allowed to run code.
693      */
694     final SparseArray<UserState> mStartedUsers = new SparseArray<>();
695
696     /**
697      * LRU list of history of current users.  Most recently current is at the end.
698      */
699     final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
700
701     /**
702      * Constant array of the users that are currently started.
703      */
704     int[] mStartedUserArray = new int[] { 0 };
705
706     /**
707      * Registered observers of the user switching mechanics.
708      */
709     final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
710             = new RemoteCallbackList<IUserSwitchObserver>();
711
712     /**
713      * Currently active user switch.
714      */
715     Object mCurUserSwitchCallback;
716
717     /**
718      * Packages that the user has asked to have run in screen size
719      * compatibility mode instead of filling the screen.
720      */
721     final CompatModePackages mCompatModePackages;
722
723     /**
724      * Set of IntentSenderRecord objects that are currently active.
725      */
726     final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
727             = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
728
729     /**
730      * Fingerprints (hashCode()) of stack traces that we've
731      * already logged DropBox entries for.  Guarded by itself.  If
732      * something (rogue user app) forces this over
733      * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
734      */
735     private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
736     private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
737
738     /**
739      * Strict Mode background batched logging state.
740      *
741      * The string buffer is guarded by itself, and its lock is also
742      * used to determine if another batched write is already
743      * in-flight.
744      */
745     private final StringBuilder mStrictModeBuffer = new StringBuilder();
746
747     /**
748      * Keeps track of all IIntentReceivers that have been registered for broadcasts.
749      * Hash keys are the receiver IBinder, hash value is a ReceiverList.
750      */
751     final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
752
753     /**
754      * Resolver for broadcast intents to registered receivers.
755      * Holds BroadcastFilter (subclass of IntentFilter).
756      */
757     final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
758             = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
759         @Override
760         protected boolean allowFilterResult(
761                 BroadcastFilter filter, List<BroadcastFilter> dest) {
762             IBinder target = filter.receiverList.receiver.asBinder();
763             for (int i = dest.size() - 1; i >= 0; i--) {
764                 if (dest.get(i).receiverList.receiver.asBinder() == target) {
765                     return false;
766                 }
767             }
768             return true;
769         }
770
771         @Override
772         protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
773             if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
774                     || userId == filter.owningUserId) {
775                 return super.newResult(filter, match, userId);
776             }
777             return null;
778         }
779
780         @Override
781         protected BroadcastFilter[] newArray(int size) {
782             return new BroadcastFilter[size];
783         }
784
785         @Override
786         protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
787             return packageName.equals(filter.packageName);
788         }
789     };
790
791     /**
792      * State of all active sticky broadcasts per user.  Keys are the action of the
793      * sticky Intent, values are an ArrayList of all broadcasted intents with
794      * that action (which should usually be one).  The SparseArray is keyed
795      * by the user ID the sticky is for, and can include UserHandle.USER_ALL
796      * for stickies that are sent to all users.
797      */
798     final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
799             new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
800
801     final ActiveServices mServices;
802
803     final static class Association {
804         final int mSourceUid;
805         final String mSourceProcess;
806         final int mTargetUid;
807         final ComponentName mTargetComponent;
808         final String mTargetProcess;
809
810         int mCount;
811         long mTime;
812
813         int mNesting;
814         long mStartTime;
815
816         Association(int sourceUid, String sourceProcess, int targetUid,
817                 ComponentName targetComponent, String targetProcess) {
818             mSourceUid = sourceUid;
819             mSourceProcess = sourceProcess;
820             mTargetUid = targetUid;
821             mTargetComponent = targetComponent;
822             mTargetProcess = targetProcess;
823         }
824     }
825
826     /**
827      * When service association tracking is enabled, this is all of the associations we
828      * have seen.  Mapping is target uid -> target component -> source uid -> source process name
829      * -> association data.
830      */
831     final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
832             mAssociations = new SparseArray<>();
833     boolean mTrackingAssociations;
834
835     /**
836      * Backup/restore process management
837      */
838     String mBackupAppName = null;
839     BackupRecord mBackupTarget = null;
840
841     final ProviderMap mProviderMap;
842
843     /**
844      * List of content providers who have clients waiting for them.  The
845      * application is currently being launched and the provider will be
846      * removed from this list once it is published.
847      */
848     final ArrayList<ContentProviderRecord> mLaunchingProviders
849             = new ArrayList<ContentProviderRecord>();
850
851     /**
852      * File storing persisted {@link #mGrantedUriPermissions}.
853      */
854     private final AtomicFile mGrantFile;
855
856     /** XML constants used in {@link #mGrantFile} */
857     private static final String TAG_URI_GRANTS = "uri-grants";
858     private static final String TAG_URI_GRANT = "uri-grant";
859     private static final String ATTR_USER_HANDLE = "userHandle";
860     private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
861     private static final String ATTR_TARGET_USER_ID = "targetUserId";
862     private static final String ATTR_SOURCE_PKG = "sourcePkg";
863     private static final String ATTR_TARGET_PKG = "targetPkg";
864     private static final String ATTR_URI = "uri";
865     private static final String ATTR_MODE_FLAGS = "modeFlags";
866     private static final String ATTR_CREATED_TIME = "createdTime";
867     private static final String ATTR_PREFIX = "prefix";
868
869     /**
870      * Global set of specific {@link Uri} permissions that have been granted.
871      * This optimized lookup structure maps from {@link UriPermission#targetUid}
872      * to {@link UriPermission#uri} to {@link UriPermission}.
873      */
874     @GuardedBy("this")
875     private final SparseArray<ArrayMap<GrantUri, UriPermission>>
876             mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
877
878     public static class GrantUri {
879         public final int sourceUserId;
880         public final Uri uri;
881         public boolean prefix;
882
883         public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
884             this.sourceUserId = sourceUserId;
885             this.uri = uri;
886             this.prefix = prefix;
887         }
888
889         @Override
890         public int hashCode() {
891             int hashCode = 1;
892             hashCode = 31 * hashCode + sourceUserId;
893             hashCode = 31 * hashCode + uri.hashCode();
894             hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
895             return hashCode;
896         }
897
898         @Override
899         public boolean equals(Object o) {
900             if (o instanceof GrantUri) {
901                 GrantUri other = (GrantUri) o;
902                 return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
903                         && prefix == other.prefix;
904             }
905             return false;
906         }
907
908         @Override
909         public String toString() {
910             String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
911             if (prefix) result += " [prefix]";
912             return result;
913         }
914
915         public String toSafeString() {
916             String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
917             if (prefix) result += " [prefix]";
918             return result;
919         }
920
921         public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
922             return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
923                     ContentProvider.getUriWithoutUserId(uri), false);
924         }
925     }
926
927     CoreSettingsObserver mCoreSettingsObserver;
928
929     /**
930      * Thread-local storage used to carry caller permissions over through
931      * indirect content-provider access.
932      */
933     private class Identity {
934         public final IBinder token;
935         public final int pid;
936         public final int uid;
937
938         Identity(IBinder _token, int _pid, int _uid) {
939             token = _token;
940             pid = _pid;
941             uid = _uid;
942         }
943     }
944
945     private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
946
947     /**
948      * All information we have collected about the runtime performance of
949      * any user id that can impact battery performance.
950      */
951     final BatteryStatsService mBatteryStatsService;
952
953     /**
954      * Information about component usage
955      */
956     UsageStatsManagerInternal mUsageStatsService;
957
958     /**
959      * Access to DeviceIdleController service.
960      */
961     DeviceIdleController.LocalService mLocalDeviceIdleController;
962
963     /**
964      * Information about and control over application operations
965      */
966     final AppOpsService mAppOpsService;
967
968     /**
969      * Save recent tasks information across reboots.
970      */
971     final TaskPersister mTaskPersister;
972
973     /**
974      * Current configuration information.  HistoryRecord objects are given
975      * a reference to this object to indicate which configuration they are
976      * currently running in, so this object must be kept immutable.
977      */
978     Configuration mConfiguration = new Configuration();
979
980     /**
981      * Current sequencing integer of the configuration, for skipping old
982      * configurations.
983      */
984     int mConfigurationSeq = 0;
985
986     /**
987      * Hardware-reported OpenGLES version.
988      */
989     final int GL_ES_VERSION;
990
991     /**
992      * List of initialization arguments to pass to all processes when binding applications to them.
993      * For example, references to the commonly used services.
994      */
995     HashMap<String, IBinder> mAppBindArgs;
996
997     /**
998      * Temporary to avoid allocations.  Protected by main lock.
999      */
1000     final StringBuilder mStringBuilder = new StringBuilder(256);
1001
1002     /**
1003      * Used to control how we initialize the service.
1004      */
1005     ComponentName mTopComponent;
1006     String mTopAction = Intent.ACTION_MAIN;
1007     String mTopData;
1008     boolean mProcessesReady = false;
1009     boolean mSystemReady = false;
1010     boolean mBooting = false;
1011     boolean mCallFinishBooting = false;
1012     boolean mBootAnimationComplete = false;
1013     boolean mWaitingUpdate = false;
1014     boolean mDidUpdate = false;
1015     boolean mOnBattery = false;
1016     boolean mLaunchWarningShown = false;
1017
1018     Context mContext;
1019
1020     int mFactoryTest;
1021
1022     boolean mCheckedForSetup;
1023
1024     /**
1025      * The time at which we will allow normal application switches again,
1026      * after a call to {@link #stopAppSwitches()}.
1027      */
1028     long mAppSwitchesAllowedTime;
1029
1030     /**
1031      * This is set to true after the first switch after mAppSwitchesAllowedTime
1032      * is set; any switches after that will clear the time.
1033      */
1034     boolean mDidAppSwitch;
1035
1036     /**
1037      * Last time (in realtime) at which we checked for power usage.
1038      */
1039     long mLastPowerCheckRealtime;
1040
1041     /**
1042      * Last time (in uptime) at which we checked for power usage.
1043      */
1044     long mLastPowerCheckUptime;
1045
1046     /**
1047      * Set while we are wanting to sleep, to prevent any
1048      * activities from being started/resumed.
1049      */
1050     private boolean mSleeping = false;
1051
1052     /**
1053      * The process state used for processes that are running the top activities.
1054      * This changes between TOP and TOP_SLEEPING to following mSleeping.
1055      */
1056     int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1057
1058     /**
1059      * Set while we are running a voice interaction.  This overrides
1060      * sleeping while it is active.
1061      */
1062     private IVoiceInteractionSession mRunningVoice;
1063
1064     /**
1065      * For some direct access we need to power manager.
1066      */
1067     PowerManagerInternal mLocalPowerManager;
1068
1069     /**
1070      * We want to hold a wake lock while running a voice interaction session, since
1071      * this may happen with the screen off and we need to keep the CPU running to
1072      * be able to continue to interact with the user.
1073      */
1074     PowerManager.WakeLock mVoiceWakeLock;
1075
1076     /**
1077      * State of external calls telling us if the device is awake or asleep.
1078      */
1079     private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1080
1081     /**
1082      * A list of tokens that cause the top activity to be put to sleep.
1083      * They are used by components that may hide and block interaction with underlying
1084      * activities.
1085      */
1086     final ArrayList<SleepToken> mSleepTokens = new ArrayList<SleepToken>();
1087
1088     static final int LOCK_SCREEN_HIDDEN = 0;
1089     static final int LOCK_SCREEN_LEAVING = 1;
1090     static final int LOCK_SCREEN_SHOWN = 2;
1091     /**
1092      * State of external call telling us if the lock screen is shown.
1093      */
1094     int mLockScreenShown = LOCK_SCREEN_HIDDEN;
1095
1096     /**
1097      * Set if we are shutting down the system, similar to sleeping.
1098      */
1099     boolean mShuttingDown = false;
1100
1101     /**
1102      * Current sequence id for oom_adj computation traversal.
1103      */
1104     int mAdjSeq = 0;
1105
1106     /**
1107      * Current sequence id for process LRU updating.
1108      */
1109     int mLruSeq = 0;
1110
1111     /**
1112      * Keep track of the non-cached/empty process we last found, to help
1113      * determine how to distribute cached/empty processes next time.
1114      */
1115     int mNumNonCachedProcs = 0;
1116
1117     /**
1118      * Keep track of the number of cached hidden procs, to balance oom adj
1119      * distribution between those and empty procs.
1120      */
1121     int mNumCachedHiddenProcs = 0;
1122
1123     /**
1124      * Keep track of the number of service processes we last found, to
1125      * determine on the next iteration which should be B services.
1126      */
1127     int mNumServiceProcs = 0;
1128     int mNewNumAServiceProcs = 0;
1129     int mNewNumServiceProcs = 0;
1130
1131     /**
1132      * Allow the current computed overall memory level of the system to go down?
1133      * This is set to false when we are killing processes for reasons other than
1134      * memory management, so that the now smaller process list will not be taken as
1135      * an indication that memory is tighter.
1136      */
1137     boolean mAllowLowerMemLevel = false;
1138
1139     /**
1140      * The last computed memory level, for holding when we are in a state that
1141      * processes are going away for other reasons.
1142      */
1143     int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1144
1145     /**
1146      * The last total number of process we have, to determine if changes actually look
1147      * like a shrinking number of process due to lower RAM.
1148      */
1149     int mLastNumProcesses;
1150
1151     /**
1152      * The uptime of the last time we performed idle maintenance.
1153      */
1154     long mLastIdleTime = SystemClock.uptimeMillis();
1155
1156     /**
1157      * Total time spent with RAM that has been added in the past since the last idle time.
1158      */
1159     long mLowRamTimeSinceLastIdle = 0;
1160
1161     /**
1162      * If RAM is currently low, when that horrible situation started.
1163      */
1164     long mLowRamStartTime = 0;
1165
1166     /**
1167      * For reporting to battery stats the current top application.
1168      */
1169     private String mCurResumedPackage = null;
1170     private int mCurResumedUid = -1;
1171
1172     /**
1173      * For reporting to battery stats the apps currently running foreground
1174      * service.  The ProcessMap is package/uid tuples; each of these contain
1175      * an array of the currently foreground processes.
1176      */
1177     final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1178             = new ProcessMap<ArrayList<ProcessRecord>>();
1179
1180     /**
1181      * This is set if we had to do a delayed dexopt of an app before launching
1182      * it, to increase the ANR timeouts in that case.
1183      */
1184     boolean mDidDexOpt;
1185
1186     /**
1187      * Set if the systemServer made a call to enterSafeMode.
1188      */
1189     boolean mSafeMode;
1190
1191     /**
1192      * If true, we are running under a test environment so will sample PSS from processes
1193      * much more rapidly to try to collect better data when the tests are rapidly
1194      * running through apps.
1195      */
1196     boolean mTestPssMode = false;
1197
1198     String mDebugApp = null;
1199     boolean mWaitForDebugger = false;
1200     boolean mDebugTransient = false;
1201     String mOrigDebugApp = null;
1202     boolean mOrigWaitForDebugger = false;
1203     boolean mAlwaysFinishActivities = false;
1204     IActivityController mController = null;
1205     String mProfileApp = null;
1206     ProcessRecord mProfileProc = null;
1207     String mProfileFile;
1208     ParcelFileDescriptor mProfileFd;
1209     int mSamplingInterval = 0;
1210     boolean mAutoStopProfiler = false;
1211     int mProfileType = 0;
1212     String mOpenGlTraceApp = null;
1213     final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1214     String mMemWatchDumpProcName;
1215     String mMemWatchDumpFile;
1216     int mMemWatchDumpPid;
1217     int mMemWatchDumpUid;
1218
1219     final long[] mTmpLong = new long[1];
1220
1221     static final class ProcessChangeItem {
1222         static final int CHANGE_ACTIVITIES = 1<<0;
1223         static final int CHANGE_PROCESS_STATE = 1<<1;
1224         int changes;
1225         int uid;
1226         int pid;
1227         int processState;
1228         boolean foregroundActivities;
1229     }
1230
1231     final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1232     ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1233
1234     final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1235     final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1236
1237     final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1238     UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1239
1240     final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1241     final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1242
1243     /**
1244      * Runtime CPU use collection thread.  This object's lock is used to
1245      * perform synchronization with the thread (notifying it to run).
1246      */
1247     final Thread mProcessCpuThread;
1248
1249     /**
1250      * Used to collect per-process CPU use for ANRs, battery stats, etc.
1251      * Must acquire this object's lock when accessing it.
1252      * NOTE: this lock will be held while doing long operations (trawling
1253      * through all processes in /proc), so it should never be acquired by
1254      * any critical paths such as when holding the main activity manager lock.
1255      */
1256     final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1257             MONITOR_THREAD_CPU_USAGE);
1258     final AtomicLong mLastCpuTime = new AtomicLong(0);
1259     final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1260
1261     long mLastWriteTime = 0;
1262
1263     /**
1264      * Used to retain an update lock when the foreground activity is in
1265      * immersive mode.
1266      */
1267     final UpdateLock mUpdateLock = new UpdateLock("immersive");
1268
1269     /**
1270      * Set to true after the system has finished booting.
1271      */
1272     boolean mBooted = false;
1273
1274     int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1275     int mProcessLimitOverride = -1;
1276
1277     WindowManagerService mWindowManager;
1278
1279     final ActivityThread mSystemThread;
1280
1281     // Holds the current foreground user's id
1282     int mCurrentUserId = 0;
1283     // Holds the target user's id during a user switch
1284     int mTargetUserId = UserHandle.USER_NULL;
1285     // If there are multiple profiles for the current user, their ids are here
1286     // Currently only the primary user can have managed profiles
1287     int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1288
1289     /**
1290      * Mapping from each known user ID to the profile group ID it is associated with.
1291      */
1292     SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray();
1293
1294     private UserManagerService mUserManager;
1295
1296     private final class AppDeathRecipient implements IBinder.DeathRecipient {
1297         final ProcessRecord mApp;
1298         final int mPid;
1299         final IApplicationThread mAppThread;
1300
1301         AppDeathRecipient(ProcessRecord app, int pid,
1302                 IApplicationThread thread) {
1303             if (DEBUG_ALL) Slog.v(
1304                 TAG, "New death recipient " + this
1305                 + " for thread " + thread.asBinder());
1306             mApp = app;
1307             mPid = pid;
1308             mAppThread = thread;
1309         }
1310
1311         @Override
1312         public void binderDied() {
1313             if (DEBUG_ALL) Slog.v(
1314                 TAG, "Death received in " + this
1315                 + " for thread " + mAppThread.asBinder());
1316             synchronized(ActivityManagerService.this) {
1317                 appDiedLocked(mApp, mPid, mAppThread, true);
1318             }
1319         }
1320     }
1321
1322     static final int SHOW_ERROR_MSG = 1;
1323     static final int SHOW_NOT_RESPONDING_MSG = 2;
1324     static final int SHOW_FACTORY_ERROR_MSG = 3;
1325     static final int UPDATE_CONFIGURATION_MSG = 4;
1326     static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1327     static final int WAIT_FOR_DEBUGGER_MSG = 6;
1328     static final int SERVICE_TIMEOUT_MSG = 12;
1329     static final int UPDATE_TIME_ZONE = 13;
1330     static final int SHOW_UID_ERROR_MSG = 14;
1331     static final int SHOW_FINGERPRINT_ERROR_MSG = 15;
1332     static final int PROC_START_TIMEOUT_MSG = 20;
1333     static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1334     static final int KILL_APPLICATION_MSG = 22;
1335     static final int FINALIZE_PENDING_INTENT_MSG = 23;
1336     static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1337     static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1338     static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1339     static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1340     static final int CLEAR_DNS_CACHE_MSG = 28;
1341     static final int UPDATE_HTTP_PROXY_MSG = 29;
1342     static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1343     static final int DISPATCH_PROCESSES_CHANGED = 31;
1344     static final int DISPATCH_PROCESS_DIED = 32;
1345     static final int REPORT_MEM_USAGE_MSG = 33;
1346     static final int REPORT_USER_SWITCH_MSG = 34;
1347     static final int CONTINUE_USER_SWITCH_MSG = 35;
1348     static final int USER_SWITCH_TIMEOUT_MSG = 36;
1349     static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1350     static final int PERSIST_URI_GRANTS_MSG = 38;
1351     static final int REQUEST_ALL_PSS_MSG = 39;
1352     static final int START_PROFILES_MSG = 40;
1353     static final int UPDATE_TIME = 41;
1354     static final int SYSTEM_USER_START_MSG = 42;
1355     static final int SYSTEM_USER_CURRENT_MSG = 43;
1356     static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1357     static final int FINISH_BOOTING_MSG = 45;
1358     static final int START_USER_SWITCH_MSG = 46;
1359     static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1360     static final int DISMISS_DIALOG_MSG = 48;
1361     static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49;
1362     static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 50;
1363     static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 51;
1364     static final int DELETE_DUMPHEAP_MSG = 52;
1365     static final int FOREGROUND_PROFILE_CHANGED_MSG = 53;
1366     static final int DISPATCH_UIDS_CHANGED_MSG = 54;
1367     static final int REPORT_TIME_TRACKER_MSG = 55;
1368     static final int REPORT_USER_SWITCH_COMPLETE_MSG = 56;
1369     static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 57;
1370     static final int APP_BOOST_DEACTIVATE_MSG = 58;
1371
1372     static final int FIRST_ACTIVITY_STACK_MSG = 100;
1373     static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1374     static final int FIRST_COMPAT_MODE_MSG = 300;
1375     static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1376
1377     CompatModeDialog mCompatModeDialog;
1378     long mLastMemUsageReportTime = 0;
1379
1380     /**
1381      * Flag whether the current user is a "monkey", i.e. whether
1382      * the UI is driven by a UI automation tool.
1383      */
1384     private boolean mUserIsMonkey;
1385
1386     /** Flag whether the device has a Recents UI */
1387     boolean mHasRecents;
1388
1389     /** The dimensions of the thumbnails in the Recents UI. */
1390     int mThumbnailWidth;
1391     int mThumbnailHeight;
1392
1393     final ServiceThread mHandlerThread;
1394     final MainHandler mHandler;
1395     final UiHandler mUiHandler;
1396
1397     final class UiHandler extends Handler {
1398         public UiHandler() {
1399             super(com.android.server.UiThread.get().getLooper(), null, true);
1400         }
1401
1402         @Override
1403         public void handleMessage(Message msg) {
1404             switch (msg.what) {
1405             case SHOW_ERROR_MSG: {
1406                 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1407                 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1408                         Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1409                 synchronized (ActivityManagerService.this) {
1410                     ProcessRecord proc = (ProcessRecord)data.get("app");
1411                     AppErrorResult res = (AppErrorResult) data.get("result");
1412                     if (proc != null && proc.crashDialog != null) {
1413                         Slog.e(TAG, "App already has crash dialog: " + proc);
1414                         if (res != null) {
1415                             res.set(0);
1416                         }
1417                         return;
1418                     }
1419                     boolean isBackground = (UserHandle.getAppId(proc.uid)
1420                             >= Process.FIRST_APPLICATION_UID
1421                             && proc.pid != MY_PID);
1422                     for (int userId : mCurrentProfileIds) {
1423                         isBackground &= (proc.userId != userId);
1424                     }
1425                     if (isBackground && !showBackground) {
1426                         Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1427                         if (res != null) {
1428                             res.set(0);
1429                         }
1430                         return;
1431                     }
1432                     if (mShowDialogs && !mSleeping && !mShuttingDown) {
1433                         Dialog d = new AppErrorDialog(mContext,
1434                                 ActivityManagerService.this, res, proc);
1435                         d.show();
1436                         proc.crashDialog = d;
1437                     } else {
1438                         // The device is asleep, so just pretend that the user
1439                         // saw a crash dialog and hit "force quit".
1440                         if (res != null) {
1441                             res.set(0);
1442                         }
1443                     }
1444                 }
1445
1446                 ensureBootCompleted();
1447             } break;
1448             case SHOW_NOT_RESPONDING_MSG: {
1449                 synchronized (ActivityManagerService.this) {
1450                     HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1451                     ProcessRecord proc = (ProcessRecord)data.get("app");
1452                     if (proc != null && proc.anrDialog != null) {
1453                         Slog.e(TAG, "App already has anr dialog: " + proc);
1454                         return;
1455                     }
1456
1457                     Intent intent = new Intent("android.intent.action.ANR");
1458                     if (!mProcessesReady) {
1459                         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1460                                 | Intent.FLAG_RECEIVER_FOREGROUND);
1461                     }
1462                     broadcastIntentLocked(null, null, intent,
1463                             null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1464                             null, false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1465
1466                     if (mShowDialogs) {
1467                         Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1468                                 mContext, proc, (ActivityRecord)data.get("activity"),
1469                                 msg.arg1 != 0);
1470                         d.show();
1471                         proc.anrDialog = d;
1472                     } else {
1473                         // Just kill the app if there is no dialog to be shown.
1474                         killAppAtUsersRequest(proc, null);
1475                     }
1476                 }
1477
1478                 ensureBootCompleted();
1479             } break;
1480             case SHOW_STRICT_MODE_VIOLATION_MSG: {
1481                 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1482                 synchronized (ActivityManagerService.this) {
1483                     ProcessRecord proc = (ProcessRecord) data.get("app");
1484                     if (proc == null) {
1485                         Slog.e(TAG, "App not found when showing strict mode dialog.");
1486                         break;
1487                     }
1488                     if (proc.crashDialog != null) {
1489                         Slog.e(TAG, "App already has strict mode dialog: " + proc);
1490                         return;
1491                     }
1492                     AppErrorResult res = (AppErrorResult) data.get("result");
1493                     if (mShowDialogs && !mSleeping && !mShuttingDown) {
1494                         Dialog d = new StrictModeViolationDialog(mContext,
1495                                 ActivityManagerService.this, res, proc);
1496                         d.show();
1497                         proc.crashDialog = d;
1498                     } else {
1499                         // The device is asleep, so just pretend that the user
1500                         // saw a crash dialog and hit "force quit".
1501                         res.set(0);
1502                     }
1503                 }
1504                 ensureBootCompleted();
1505             } break;
1506             case SHOW_FACTORY_ERROR_MSG: {
1507                 Dialog d = new FactoryErrorDialog(
1508                     mContext, msg.getData().getCharSequence("msg"));
1509                 d.show();
1510                 ensureBootCompleted();
1511             } break;
1512             case WAIT_FOR_DEBUGGER_MSG: {
1513                 synchronized (ActivityManagerService.this) {
1514                     ProcessRecord app = (ProcessRecord)msg.obj;
1515                     if (msg.arg1 != 0) {
1516                         if (!app.waitedForDebugger) {
1517                             Dialog d = new AppWaitingForDebuggerDialog(
1518                                     ActivityManagerService.this,
1519                                     mContext, app);
1520                             app.waitDialog = d;
1521                             app.waitedForDebugger = true;
1522                             d.show();
1523                         }
1524                     } else {
1525                         if (app.waitDialog != null) {
1526                             app.waitDialog.dismiss();
1527                             app.waitDialog = null;
1528                         }
1529                     }
1530                 }
1531             } break;
1532             case SHOW_UID_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_wipe_data));
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_FINGERPRINT_ERROR_MSG: {
1545                 if (mShowDialogs) {
1546                     AlertDialog d = new BaseErrorDialog(mContext);
1547                     d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1548                     d.setCancelable(false);
1549                     d.setTitle(mContext.getText(R.string.android_system_label));
1550                     d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1551                     d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1552                             obtainMessage(DISMISS_DIALOG_MSG, d));
1553                     d.show();
1554                 }
1555             } break;
1556             case SHOW_COMPAT_MODE_DIALOG_MSG: {
1557                 synchronized (ActivityManagerService.this) {
1558                     ActivityRecord ar = (ActivityRecord) msg.obj;
1559                     if (mCompatModeDialog != null) {
1560                         if (mCompatModeDialog.mAppInfo.packageName.equals(
1561                                 ar.info.applicationInfo.packageName)) {
1562                             return;
1563                         }
1564                         mCompatModeDialog.dismiss();
1565                         mCompatModeDialog = null;
1566                     }
1567                     if (ar != null && false) {
1568                         if (mCompatModePackages.getPackageAskCompatModeLocked(
1569                                 ar.packageName)) {
1570                             int mode = mCompatModePackages.computeCompatModeLocked(
1571                                     ar.info.applicationInfo);
1572                             if (mode == ActivityManager.COMPAT_MODE_DISABLED
1573                                     || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1574                                 mCompatModeDialog = new CompatModeDialog(
1575                                         ActivityManagerService.this, mContext,
1576                                         ar.info.applicationInfo);
1577                                 mCompatModeDialog.show();
1578                             }
1579                         }
1580                     }
1581                 }
1582                 break;
1583             }
1584             case START_USER_SWITCH_MSG: {
1585                 showUserSwitchDialog(msg.arg1, (String) msg.obj);
1586                 break;
1587             }
1588             case DISMISS_DIALOG_MSG: {
1589                 final Dialog d = (Dialog) msg.obj;
1590                 d.dismiss();
1591                 break;
1592             }
1593             case DISPATCH_PROCESSES_CHANGED: {
1594                 dispatchProcessesChanged();
1595                 break;
1596             }
1597             case DISPATCH_PROCESS_DIED: {
1598                 final int pid = msg.arg1;
1599                 final int uid = msg.arg2;
1600                 dispatchProcessDied(pid, uid);
1601                 break;
1602             }
1603             case DISPATCH_UIDS_CHANGED_MSG: {
1604                 dispatchUidsChanged();
1605             } break;
1606             }
1607         }
1608     }
1609
1610     final class MainHandler extends Handler {
1611         public MainHandler(Looper looper) {
1612             super(looper, null, true);
1613         }
1614
1615         @Override
1616         public void handleMessage(Message msg) {
1617             switch (msg.what) {
1618             case UPDATE_CONFIGURATION_MSG: {
1619                 final ContentResolver resolver = mContext.getContentResolver();
1620                 Settings.System.putConfiguration(resolver, (Configuration) msg.obj);
1621             } break;
1622             case GC_BACKGROUND_PROCESSES_MSG: {
1623                 synchronized (ActivityManagerService.this) {
1624                     performAppGcsIfAppropriateLocked();
1625                 }
1626             } break;
1627             case SERVICE_TIMEOUT_MSG: {
1628                 if (mDidDexOpt) {
1629                     mDidDexOpt = false;
1630                     Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1631                     nmsg.obj = msg.obj;
1632                     mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1633                     return;
1634                 }
1635                 mServices.serviceTimeout((ProcessRecord)msg.obj);
1636             } break;
1637             case UPDATE_TIME_ZONE: {
1638                 synchronized (ActivityManagerService.this) {
1639                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1640                         ProcessRecord r = mLruProcesses.get(i);
1641                         if (r.thread != null) {
1642                             try {
1643                                 r.thread.updateTimeZone();
1644                             } catch (RemoteException ex) {
1645                                 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1646                             }
1647                         }
1648                     }
1649                 }
1650             } break;
1651             case CLEAR_DNS_CACHE_MSG: {
1652                 synchronized (ActivityManagerService.this) {
1653                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1654                         ProcessRecord r = mLruProcesses.get(i);
1655                         if (r.thread != null) {
1656                             try {
1657                                 r.thread.clearDnsCache();
1658                             } catch (RemoteException ex) {
1659                                 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1660                             }
1661                         }
1662                     }
1663                 }
1664             } break;
1665             case UPDATE_HTTP_PROXY_MSG: {
1666                 ProxyInfo proxy = (ProxyInfo)msg.obj;
1667                 String host = "";
1668                 String port = "";
1669                 String exclList = "";
1670                 Uri pacFileUrl = Uri.EMPTY;
1671                 if (proxy != null) {
1672                     host = proxy.getHost();
1673                     port = Integer.toString(proxy.getPort());
1674                     exclList = proxy.getExclusionListAsString();
1675                     pacFileUrl = proxy.getPacFileUrl();
1676                 }
1677                 synchronized (ActivityManagerService.this) {
1678                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1679                         ProcessRecord r = mLruProcesses.get(i);
1680                         if (r.thread != null) {
1681                             try {
1682                                 r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1683                             } catch (RemoteException ex) {
1684                                 Slog.w(TAG, "Failed to update http proxy for: " +
1685                                         r.info.processName);
1686                             }
1687                         }
1688                     }
1689                 }
1690             } break;
1691             case PROC_START_TIMEOUT_MSG: {
1692                 if (mDidDexOpt) {
1693                     mDidDexOpt = false;
1694                     Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1695                     nmsg.obj = msg.obj;
1696                     mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1697                     return;
1698                 }
1699                 ProcessRecord app = (ProcessRecord)msg.obj;
1700                 synchronized (ActivityManagerService.this) {
1701                     processStartTimedOutLocked(app);
1702                 }
1703             } break;
1704             case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1705                 synchronized (ActivityManagerService.this) {
1706                     mStackSupervisor.doPendingActivityLaunchesLocked(true);
1707                 }
1708             } break;
1709             case KILL_APPLICATION_MSG: {
1710                 synchronized (ActivityManagerService.this) {
1711                     int appid = msg.arg1;
1712                     boolean restart = (msg.arg2 == 1);
1713                     Bundle bundle = (Bundle)msg.obj;
1714                     String pkg = bundle.getString("pkg");
1715                     String reason = bundle.getString("reason");
1716                     forceStopPackageLocked(pkg, appid, restart, false, true, false,
1717                             false, UserHandle.USER_ALL, reason);
1718                 }
1719             } break;
1720             case FINALIZE_PENDING_INTENT_MSG: {
1721                 ((PendingIntentRecord)msg.obj).completeFinalize();
1722             } break;
1723             case POST_HEAVY_NOTIFICATION_MSG: {
1724                 INotificationManager inm = NotificationManager.getService();
1725                 if (inm == null) {
1726                     return;
1727                 }
1728
1729                 ActivityRecord root = (ActivityRecord)msg.obj;
1730                 ProcessRecord process = root.app;
1731                 if (process == null) {
1732                     return;
1733                 }
1734
1735                 try {
1736                     Context context = mContext.createPackageContext(process.info.packageName, 0);
1737                     String text = mContext.getString(R.string.heavy_weight_notification,
1738                             context.getApplicationInfo().loadLabel(context.getPackageManager()));
1739                     Notification notification = new Notification.Builder(context)
1740                             .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
1741                             .setWhen(0)
1742                             .setOngoing(true)
1743                             .setTicker(text)
1744                             .setColor(mContext.getColor(
1745                                     com.android.internal.R.color.system_notification_accent_color))
1746                             .setContentTitle(text)
1747                             .setContentText(
1748                                     mContext.getText(R.string.heavy_weight_notification_detail))
1749                             .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
1750                                     root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
1751                                     new UserHandle(root.userId)))
1752                             .build();
1753                     try {
1754                         int[] outId = new int[1];
1755                         inm.enqueueNotificationWithTag("android", "android", null,
1756                                 R.string.heavy_weight_notification,
1757                                 notification, outId, root.userId);
1758                     } catch (RuntimeException e) {
1759                         Slog.w(ActivityManagerService.TAG,
1760                                 "Error showing notification for heavy-weight app", e);
1761                     } catch (RemoteException e) {
1762                     }
1763                 } catch (NameNotFoundException e) {
1764                     Slog.w(TAG, "Unable to create context for heavy notification", e);
1765                 }
1766             } break;
1767             case CANCEL_HEAVY_NOTIFICATION_MSG: {
1768                 INotificationManager inm = NotificationManager.getService();
1769                 if (inm == null) {
1770                     return;
1771                 }
1772                 try {
1773                     inm.cancelNotificationWithTag("android", null,
1774                             R.string.heavy_weight_notification,  msg.arg1);
1775                 } catch (RuntimeException e) {
1776                     Slog.w(ActivityManagerService.TAG,
1777                             "Error canceling notification for service", e);
1778                 } catch (RemoteException e) {
1779                 }
1780             } break;
1781             case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1782                 synchronized (ActivityManagerService.this) {
1783                     checkExcessivePowerUsageLocked(true);
1784                     removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1785                     Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1786                     sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1787                 }
1788             } break;
1789             case REPORT_MEM_USAGE_MSG: {
1790                 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1791                 Thread thread = new Thread() {
1792                     @Override public void run() {
1793                         reportMemUsage(memInfos);
1794                     }
1795                 };
1796                 thread.start();
1797                 break;
1798             }
1799             case REPORT_USER_SWITCH_MSG: {
1800                 dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1801                 break;
1802             }
1803             case CONTINUE_USER_SWITCH_MSG: {
1804                 continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1805                 break;
1806             }
1807             case USER_SWITCH_TIMEOUT_MSG: {
1808                 timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1809                 break;
1810             }
1811             case IMMERSIVE_MODE_LOCK_MSG: {
1812                 final boolean nextState = (msg.arg1 != 0);
1813                 if (mUpdateLock.isHeld() != nextState) {
1814                     if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
1815                             "Applying new update lock state '" + nextState
1816                             + "' for " + (ActivityRecord)msg.obj);
1817                     if (nextState) {
1818                         mUpdateLock.acquire();
1819                     } else {
1820                         mUpdateLock.release();
1821                     }
1822                 }
1823                 break;
1824             }
1825             case PERSIST_URI_GRANTS_MSG: {
1826                 writeGrantedUriPermissions();
1827                 break;
1828             }
1829             case REQUEST_ALL_PSS_MSG: {
1830                 synchronized (ActivityManagerService.this) {
1831                     requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1832                 }
1833                 break;
1834             }
1835             case START_PROFILES_MSG: {
1836                 synchronized (ActivityManagerService.this) {
1837                     startProfilesLocked();
1838                 }
1839                 break;
1840             }
1841             case UPDATE_TIME: {
1842                 synchronized (ActivityManagerService.this) {
1843                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1844                         ProcessRecord r = mLruProcesses.get(i);
1845                         if (r.thread != null) {
1846                             try {
1847                                 r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1848                             } catch (RemoteException ex) {
1849                                 Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1850                             }
1851                         }
1852                     }
1853                 }
1854                 break;
1855             }
1856             case SYSTEM_USER_START_MSG: {
1857                 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1858                         Integer.toString(msg.arg1), msg.arg1);
1859                 mSystemServiceManager.startUser(msg.arg1);
1860                 break;
1861             }
1862             case SYSTEM_USER_CURRENT_MSG: {
1863                 mBatteryStatsService.noteEvent(
1864                         BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1865                         Integer.toString(msg.arg2), msg.arg2);
1866                 mBatteryStatsService.noteEvent(
1867                         BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1868                         Integer.toString(msg.arg1), msg.arg1);
1869                 mSystemServiceManager.switchUser(msg.arg1);
1870                 break;
1871             }
1872             case ENTER_ANIMATION_COMPLETE_MSG: {
1873                 synchronized (ActivityManagerService.this) {
1874                     ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
1875                     if (r != null && r.app != null && r.app.thread != null) {
1876                         try {
1877                             r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1878                         } catch (RemoteException e) {
1879                         }
1880                     }
1881                 }
1882                 break;
1883             }
1884             case FINISH_BOOTING_MSG: {
1885                 if (msg.arg1 != 0) {
1886                     finishBooting();
1887                 }
1888                 if (msg.arg2 != 0) {
1889                     enableScreenAfterBoot();
1890                 }
1891                 break;
1892             }
1893             case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
1894                 try {
1895                     Locale l = (Locale) msg.obj;
1896                     IBinder service = ServiceManager.getService("mount");
1897                     IMountService mountService = IMountService.Stub.asInterface(service);
1898                     Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
1899                     mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
1900                 } catch (RemoteException e) {
1901                     Log.e(TAG, "Error storing locale for decryption UI", e);
1902                 }
1903                 break;
1904             }
1905             case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: {
1906                 synchronized (ActivityManagerService.this) {
1907                     int i = mTaskStackListeners.beginBroadcast();
1908                     while (i > 0) {
1909                         i--;
1910                         try {
1911                             // Make a one-way callback to the listener
1912                             mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged();
1913                         } catch (RemoteException e){
1914                             // Handled by the RemoteCallbackList
1915                         }
1916                     }
1917                     mTaskStackListeners.finishBroadcast();
1918                 }
1919                 break;
1920             }
1921             case NOTIFY_CLEARTEXT_NETWORK_MSG: {
1922                 final int uid = msg.arg1;
1923                 final byte[] firstPacket = (byte[]) msg.obj;
1924
1925                 synchronized (mPidsSelfLocked) {
1926                     for (int i = 0; i < mPidsSelfLocked.size(); i++) {
1927                         final ProcessRecord p = mPidsSelfLocked.valueAt(i);
1928                         if (p.uid == uid) {
1929                             try {
1930                                 p.thread.notifyCleartextNetwork(firstPacket);
1931                             } catch (RemoteException ignored) {
1932                             }
1933                         }
1934                     }
1935                 }
1936                 break;
1937             }
1938             case POST_DUMP_HEAP_NOTIFICATION_MSG: {
1939                 final String procName;
1940                 final int uid;
1941                 final long memLimit;
1942                 final String reportPackage;
1943                 synchronized (ActivityManagerService.this) {
1944                     procName = mMemWatchDumpProcName;
1945                     uid = mMemWatchDumpUid;
1946                     Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
1947                     if (val == null) {
1948                         val = mMemWatchProcesses.get(procName, 0);
1949                     }
1950                     if (val != null) {
1951                         memLimit = val.first;
1952                         reportPackage = val.second;
1953                     } else {
1954                         memLimit = 0;
1955                         reportPackage = null;
1956                     }
1957                 }
1958                 if (procName == null) {
1959                     return;
1960                 }
1961
1962                 if (DEBUG_PSS) Slog.d(TAG_PSS,
1963                         "Showing dump heap notification from " + procName + "/" + uid);
1964
1965                 INotificationManager inm = NotificationManager.getService();
1966                 if (inm == null) {
1967                     return;
1968                 }
1969
1970                 String text = mContext.getString(R.string.dump_heap_notification, procName);
1971
1972
1973                 Intent deleteIntent = new Intent();
1974                 deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
1975                 Intent intent = new Intent();
1976                 intent.setClassName("android", DumpHeapActivity.class.getName());
1977                 intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
1978                 intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
1979                 if (reportPackage != null) {
1980                     intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
1981                 }
1982                 int userId = UserHandle.getUserId(uid);
1983                 Notification notification = new Notification.Builder(mContext)
1984                         .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
1985                         .setWhen(0)
1986                         .setOngoing(true)
1987                         .setAutoCancel(true)
1988                         .setTicker(text)
1989                         .setColor(mContext.getColor(
1990                                 com.android.internal.R.color.system_notification_accent_color))
1991                         .setContentTitle(text)
1992                         .setContentText(
1993                                 mContext.getText(R.string.dump_heap_notification_detail))
1994                         .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
1995                                 intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
1996                                 new UserHandle(userId)))
1997                         .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
1998                                 deleteIntent, 0, UserHandle.OWNER))
1999                         .build();
2000
2001                 try {
2002                     int[] outId = new int[1];
2003                     inm.enqueueNotificationWithTag("android", "android", null,
2004                             R.string.dump_heap_notification,
2005                             notification, outId, userId);
2006                 } catch (RuntimeException e) {
2007                     Slog.w(ActivityManagerService.TAG,
2008                             "Error showing notification for dump heap", e);
2009                 } catch (RemoteException e) {
2010                 }
2011             } break;
2012             case DELETE_DUMPHEAP_MSG: {
2013                 revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2014                         DumpHeapActivity.JAVA_URI,
2015                         Intent.FLAG_GRANT_READ_URI_PERMISSION
2016                                 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2017                         UserHandle.myUserId());
2018                 synchronized (ActivityManagerService.this) {
2019                     mMemWatchDumpFile = null;
2020                     mMemWatchDumpProcName = null;
2021                     mMemWatchDumpPid = -1;
2022                     mMemWatchDumpUid = -1;
2023                 }
2024             } break;
2025             case FOREGROUND_PROFILE_CHANGED_MSG: {
2026                 dispatchForegroundProfileChanged(msg.arg1);
2027             } break;
2028             case REPORT_TIME_TRACKER_MSG: {
2029                 AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2030                 tracker.deliverResult(mContext);
2031             } break;
2032             case REPORT_USER_SWITCH_COMPLETE_MSG: {
2033                 dispatchUserSwitchComplete(msg.arg1);
2034             } break;
2035             case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2036                 IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2037                 try {
2038                     connection.shutdown();
2039                 } catch (RemoteException e) {
2040                     Slog.w(TAG, "Error shutting down UiAutomationConnection");
2041                 }
2042                 // Only a UiAutomation can set this flag and now that
2043                 // it is finished we make sure it is reset to its default.
2044                 mUserIsMonkey = false;
2045             } break;
2046             case APP_BOOST_DEACTIVATE_MSG : {
2047                 synchronized(ActivityManagerService.this) {
2048                     if (mIsBoosted) {
2049                         if (mBoostStartTime < (SystemClock.uptimeMillis() - APP_BOOST_TIMEOUT)) {
2050                             nativeMigrateFromBoost();
2051                             mIsBoosted = false;
2052                             mBoostStartTime = 0;
2053                         } else {
2054                             Message newmsg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
2055                             mHandler.sendMessageDelayed(newmsg, APP_BOOST_TIMEOUT);
2056                         }
2057                     }
2058                 }
2059             } break;
2060             }
2061         }
2062     };
2063
2064     static final int COLLECT_PSS_BG_MSG = 1;
2065
2066     final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2067         @Override
2068         public void handleMessage(Message msg) {
2069             switch (msg.what) {
2070             case COLLECT_PSS_BG_MSG: {
2071                 long start = SystemClock.uptimeMillis();
2072                 MemInfoReader memInfo = null;
2073                 synchronized (ActivityManagerService.this) {
2074                     if (mFullPssPending) {
2075                         mFullPssPending = false;
2076                         memInfo = new MemInfoReader();
2077                     }
2078                 }
2079                 if (memInfo != null) {
2080                     updateCpuStatsNow();
2081                     long nativeTotalPss = 0;
2082                     synchronized (mProcessCpuTracker) {
2083                         final int N = mProcessCpuTracker.countStats();
2084                         for (int j=0; j<N; j++) {
2085                             ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
2086                             if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
2087                                 // This is definitely an application process; skip it.
2088                                 continue;
2089                             }
2090                             synchronized (mPidsSelfLocked) {
2091                                 if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
2092                                     // This is one of our own processes; skip it.
2093                                     continue;
2094                                 }
2095                             }
2096                             nativeTotalPss += Debug.getPss(st.pid, null, null);
2097                         }
2098                     }
2099                     memInfo.readMemInfo();
2100                     synchronized (ActivityManagerService.this) {
2101                         if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2102                                 + (SystemClock.uptimeMillis()-start) + "ms");
2103                         final long cachedKb = memInfo.getCachedSizeKb();
2104                         final long freeKb = memInfo.getFreeSizeKb();
2105                         final long zramKb = memInfo.getZramTotalSizeKb();
2106                         final long kernelKb = memInfo.getKernelUsedSizeKb();
2107                         EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2108                                 kernelKb*1024, nativeTotalPss*1024);
2109                         mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2110                                 nativeTotalPss);
2111                     }
2112                 }
2113
2114                 int num = 0;
2115                 long[] tmp = new long[1];
2116                 do {
2117                     ProcessRecord proc;
2118                     int procState;
2119                     int pid;
2120                     long lastPssTime;
2121                     synchronized (ActivityManagerService.this) {
2122                         if (mPendingPssProcesses.size() <= 0) {
2123                             if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2124                                     "Collected PSS of " + num + " processes in "
2125                                     + (SystemClock.uptimeMillis() - start) + "ms");
2126                             mPendingPssProcesses.clear();
2127                             return;
2128                         }
2129                         proc = mPendingPssProcesses.remove(0);
2130                         procState = proc.pssProcState;
2131                         lastPssTime = proc.lastPssTime;
2132                         if (proc.thread != null && procState == proc.setProcState
2133                                 && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2134                                         < SystemClock.uptimeMillis()) {
2135                             pid = proc.pid;
2136                         } else {
2137                             proc = null;
2138                             pid = 0;
2139                         }
2140                     }
2141                     if (proc != null) {
2142                         long pss = Debug.getPss(pid, tmp, null);
2143                         synchronized (ActivityManagerService.this) {
2144                             if (pss != 0 && proc.thread != null && proc.setProcState == procState
2145                                     && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2146                                 num++;
2147                                 recordPssSampleLocked(proc, procState, pss, tmp[0],
2148                                         SystemClock.uptimeMillis());
2149                             }
2150                         }
2151                     }
2152                 } while (true);
2153             }
2154             }
2155         }
2156     };
2157
2158     public void setSystemProcess() {
2159         try {
2160             ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2161             ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2162             ServiceManager.addService("meminfo", new MemBinder(this));
2163             ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2164             ServiceManager.addService("dbinfo", new DbBinder(this));
2165             if (MONITOR_CPU_USAGE) {
2166                 ServiceManager.addService("cpuinfo", new CpuBinder(this));
2167             }
2168             ServiceManager.addService("permission", new PermissionController(this));
2169             ServiceManager.addService("processinfo", new ProcessInfoService(this));
2170
2171             ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2172                     "android", STOCK_PM_FLAGS);
2173             mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2174
2175             synchronized (this) {
2176                 ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2177                 app.persistent = true;
2178                 app.pid = MY_PID;
2179                 app.maxAdj = ProcessList.SYSTEM_ADJ;
2180                 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2181                 synchronized (mPidsSelfLocked) {
2182                     mPidsSelfLocked.put(app.pid, app);
2183                 }
2184                 updateLruProcessLocked(app, false, null);
2185                 updateOomAdjLocked();
2186             }
2187         } catch (PackageManager.NameNotFoundException e) {
2188             throw new RuntimeException(
2189                     "Unable to find android system package", e);
2190         }
2191     }
2192
2193     public void setWindowManager(WindowManagerService wm) {
2194         mWindowManager = wm;
2195         mStackSupervisor.setWindowManager(wm);
2196     }
2197
2198     public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2199         mUsageStatsService = usageStatsManager;
2200     }
2201
2202     public void startObservingNativeCrashes() {
2203         final NativeCrashListener ncl = new NativeCrashListener(this);
2204         ncl.start();
2205     }
2206
2207     public IAppOpsService getAppOpsService() {
2208         return mAppOpsService;
2209     }
2210
2211     static class MemBinder extends Binder {
2212         ActivityManagerService mActivityManagerService;
2213         MemBinder(ActivityManagerService activityManagerService) {
2214             mActivityManagerService = activityManagerService;
2215         }
2216
2217         @Override
2218         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2219             if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2220                     != PackageManager.PERMISSION_GRANTED) {
2221                 pw.println("Permission Denial: can't dump meminfo from from pid="
2222                         + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2223                         + " without permission " + android.Manifest.permission.DUMP);
2224                 return;
2225             }
2226
2227             mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2228         }
2229     }
2230
2231     static class GraphicsBinder extends Binder {
2232         ActivityManagerService mActivityManagerService;
2233         GraphicsBinder(ActivityManagerService activityManagerService) {
2234             mActivityManagerService = activityManagerService;
2235         }
2236
2237         @Override
2238         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2239             if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2240                     != PackageManager.PERMISSION_GRANTED) {
2241                 pw.println("Permission Denial: can't dump gfxinfo from from pid="
2242                         + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2243                         + " without permission " + android.Manifest.permission.DUMP);
2244                 return;
2245             }
2246
2247             mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2248         }
2249     }
2250
2251     static class DbBinder extends Binder {
2252         ActivityManagerService mActivityManagerService;
2253         DbBinder(ActivityManagerService activityManagerService) {
2254             mActivityManagerService = activityManagerService;
2255         }
2256
2257         @Override
2258         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2259             if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2260                     != PackageManager.PERMISSION_GRANTED) {
2261                 pw.println("Permission Denial: can't dump dbinfo from from pid="
2262                         + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2263                         + " without permission " + android.Manifest.permission.DUMP);
2264                 return;
2265             }
2266
2267             mActivityManagerService.dumpDbInfo(fd, pw, args);
2268         }
2269     }
2270
2271     static class CpuBinder extends Binder {
2272         ActivityManagerService mActivityManagerService;
2273         CpuBinder(ActivityManagerService activityManagerService) {
2274             mActivityManagerService = activityManagerService;
2275         }
2276
2277         @Override
2278         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2279             if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2280                     != PackageManager.PERMISSION_GRANTED) {
2281                 pw.println("Permission Denial: can't dump cpuinfo from from pid="
2282                         + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2283                         + " without permission " + android.Manifest.permission.DUMP);
2284                 return;
2285             }
2286
2287             synchronized (mActivityManagerService.mProcessCpuTracker) {
2288                 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2289                 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2290                         SystemClock.uptimeMillis()));
2291             }
2292         }
2293     }
2294
2295     public static final class Lifecycle extends SystemService {
2296         private final ActivityManagerService mService;
2297
2298         public Lifecycle(Context context) {
2299             super(context);
2300             mService = new ActivityManagerService(context);
2301         }
2302
2303         @Override
2304         public void onStart() {
2305             mService.start();
2306         }
2307
2308         public ActivityManagerService getService() {
2309             return mService;
2310         }
2311     }
2312
2313     // Note: This method is invoked on the main thread but may need to attach various
2314     // handlers to other threads.  So take care to be explicit about the looper.
2315     public ActivityManagerService(Context systemContext) {
2316         mContext = systemContext;
2317         mFactoryTest = FactoryTest.getMode();
2318         mSystemThread = ActivityThread.currentActivityThread();
2319
2320         Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2321
2322         mHandlerThread = new ServiceThread(TAG,
2323                 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2324         mHandlerThread.start();
2325         mHandler = new MainHandler(mHandlerThread.getLooper());
2326         mUiHandler = new UiHandler();
2327
2328         mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2329                 "foreground", BROADCAST_FG_TIMEOUT, false);
2330         mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2331                 "background", BROADCAST_BG_TIMEOUT, true);
2332         mBroadcastQueues[0] = mFgBroadcastQueue;
2333         mBroadcastQueues[1] = mBgBroadcastQueue;
2334
2335         mServices = new ActiveServices(this);
2336         mProviderMap = new ProviderMap(this);
2337
2338         // TODO: Move creation of battery stats service outside of activity manager service.
2339         File dataDir = Environment.getDataDirectory();
2340         File systemDir = new File(dataDir, "system");
2341         systemDir.mkdirs();
2342         mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2343         mBatteryStatsService.getActiveStatistics().readLocked();
2344         mBatteryStatsService.scheduleWriteToDisk();
2345         mOnBattery = DEBUG_POWER ? true
2346                 : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2347         mBatteryStatsService.getActiveStatistics().setCallback(this);
2348
2349         mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2350
2351         mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2352
2353         mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2354
2355         // User 0 is the first and only user that runs at boot.
2356         mStartedUsers.put(UserHandle.USER_OWNER, new UserState(UserHandle.OWNER, true));
2357         mUserLru.add(UserHandle.USER_OWNER);
2358         updateStartedUserArrayLocked();
2359
2360         GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2361             ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2362
2363         mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2364
2365         mConfiguration.setToDefaults();
2366         mConfiguration.setLocale(Locale.getDefault());
2367
2368         mConfigurationSeq = mConfiguration.seq = 1;
2369         mProcessCpuTracker.init();
2370
2371         mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2372         mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2373         mRecentTasks = new RecentTasks(this);
2374         mStackSupervisor = new ActivityStackSupervisor(this, mRecentTasks);
2375         mTaskPersister = new TaskPersister(systemDir, mStackSupervisor, mRecentTasks);
2376
2377         mProcessCpuThread = new Thread("CpuTracker") {
2378             @Override
2379             public void run() {
2380                 while (true) {
2381                     try {
2382                         try {
2383                             synchronized(this) {
2384                                 final long now = SystemClock.uptimeMillis();
2385                                 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2386                                 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2387                                 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2388                                 //        + ", write delay=" + nextWriteDelay);
2389                                 if (nextWriteDelay < nextCpuDelay) {
2390                                     nextCpuDelay = nextWriteDelay;
2391                                 }
2392                                 if (nextCpuDelay > 0) {
2393                                     mProcessCpuMutexFree.set(true);
2394                                     this.wait(nextCpuDelay);
2395                                 }
2396                             }
2397                         } catch (InterruptedException e) {
2398                         }
2399                         updateCpuStatsNow();
2400                     } catch (Exception e) {
2401                         Slog.e(TAG, "Unexpected exception collecting process stats", e);
2402                     }
2403                 }
2404             }
2405         };
2406
2407         Watchdog.getInstance().addMonitor(this);
2408         Watchdog.getInstance().addThread(mHandler);
2409     }
2410
2411     public void setSystemServiceManager(SystemServiceManager mgr) {
2412         mSystemServiceManager = mgr;
2413     }
2414
2415     public void setInstaller(Installer installer) {
2416         mInstaller = installer;
2417     }
2418
2419     private void start() {
2420         Process.removeAllProcessGroups();
2421         mProcessCpuThread.start();
2422
2423         mBatteryStatsService.publish(mContext);
2424         mAppOpsService.publish(mContext);
2425         Slog.d("AppOps", "AppOpsService published");
2426         LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2427     }
2428
2429     public void initPowerManagement() {
2430         mStackSupervisor.initPowerManagement();
2431         mBatteryStatsService.initPowerManagement();
2432         mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2433         PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2434         mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2435         mVoiceWakeLock.setReferenceCounted(false);
2436     }
2437
2438     @Override
2439     public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2440             throws RemoteException {
2441         if (code == SYSPROPS_TRANSACTION) {
2442             // We need to tell all apps about the system property change.
2443             ArrayList<IBinder> procs = new ArrayList<IBinder>();
2444             synchronized(this) {
2445                 final int NP = mProcessNames.getMap().size();
2446                 for (int ip=0; ip<NP; ip++) {
2447                     SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2448                     final int NA = apps.size();
2449                     for (int ia=0; ia<NA; ia++) {
2450                         ProcessRecord app = apps.valueAt(ia);
2451                         if (app.thread != null) {
2452                             procs.add(app.thread.asBinder());
2453                         }
2454                     }
2455                 }
2456             }
2457
2458             int N = procs.size();
2459             for (int i=0; i<N; i++) {
2460                 Parcel data2 = Parcel.obtain();
2461                 try {
2462                     procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2463                 } catch (RemoteException e) {
2464                 }
2465                 data2.recycle();
2466             }
2467         }
2468         try {
2469             return super.onTransact(code, data, reply, flags);
2470         } catch (RuntimeException e) {
2471             // The activity manager only throws security exceptions, so let's
2472             // log all others.
2473             if (!(e instanceof SecurityException)) {
2474                 Slog.wtf(TAG, "Activity Manager Crash", e);
2475             }
2476             throw e;
2477         }
2478     }
2479
2480     void updateCpuStats() {
2481         final long now = SystemClock.uptimeMillis();
2482         if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2483             return;
2484         }
2485         if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2486             synchronized (mProcessCpuThread) {
2487                 mProcessCpuThread.notify();
2488             }
2489         }
2490     }
2491
2492     void updateCpuStatsNow() {
2493         synchronized (mProcessCpuTracker) {
2494             mProcessCpuMutexFree.set(false);
2495             final long now = SystemClock.uptimeMillis();
2496             boolean haveNewCpuStats = false;
2497
2498             if (MONITOR_CPU_USAGE &&
2499                     mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2500                 mLastCpuTime.set(now);
2501                 mProcessCpuTracker.update();
2502                 if (mProcessCpuTracker.hasGoodLastStats()) {
2503                     haveNewCpuStats = true;
2504                     //Slog.i(TAG, mProcessCpu.printCurrentState());
2505                     //Slog.i(TAG, "Total CPU usage: "
2506                     //        + mProcessCpu.getTotalCpuPercent() + "%");
2507
2508                     // Slog the cpu usage if the property is set.
2509                     if ("true".equals(SystemProperties.get("events.cpu"))) {
2510                         int user = mProcessCpuTracker.getLastUserTime();
2511                         int system = mProcessCpuTracker.getLastSystemTime();
2512                         int iowait = mProcessCpuTracker.getLastIoWaitTime();
2513                         int irq = mProcessCpuTracker.getLastIrqTime();
2514                         int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2515                         int idle = mProcessCpuTracker.getLastIdleTime();
2516
2517                         int total = user + system + iowait + irq + softIrq + idle;
2518                         if (total == 0) total = 1;
2519
2520                         EventLog.writeEvent(EventLogTags.CPU,
2521                                 ((user+system+iowait+irq+softIrq) * 100) / total,
2522                                 (user * 100) / total,
2523                                 (system * 100) / total,
2524                                 (iowait * 100) / total,
2525                                 (irq * 100) / total,
2526                                 (softIrq * 100) / total);
2527                     }
2528                 }
2529             }
2530
2531             final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2532             synchronized(bstats) {
2533                 synchronized(mPidsSelfLocked) {
2534                     if (haveNewCpuStats) {
2535                         if (bstats.startAddingCpuLocked()) {
2536                             int totalUTime = 0;
2537                             int totalSTime = 0;
2538                             final int N = mProcessCpuTracker.countStats();
2539                             for (int i=0; i<N; i++) {
2540                                 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2541                                 if (!st.working) {
2542                                     continue;
2543                                 }
2544                                 ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2545                                 totalUTime += st.rel_utime;
2546                                 totalSTime += st.rel_stime;
2547                                 if (pr != null) {
2548                                     BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2549                                     if (ps == null || !ps.isActive()) {
2550                                         pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2551                                                 pr.info.uid, pr.processName);
2552                                     }
2553                                     ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2554                                     pr.curCpuTime += st.rel_utime + st.rel_stime;
2555                                 } else {
2556                                     BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2557                                     if (ps == null || !ps.isActive()) {
2558                                         st.batteryStats = ps = bstats.getProcessStatsLocked(
2559                                                 bstats.mapUid(st.uid), st.name);
2560                                     }
2561                                     ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2562                                 }
2563                             }
2564                             final int userTime = mProcessCpuTracker.getLastUserTime();
2565                             final int systemTime = mProcessCpuTracker.getLastSystemTime();
2566                             final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
2567                             final int irqTime = mProcessCpuTracker.getLastIrqTime();
2568                             final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
2569                             final int idleTime = mProcessCpuTracker.getLastIdleTime();
2570                             bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
2571                                     systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
2572                         }
2573                     }
2574                 }
2575
2576                 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2577                     mLastWriteTime = now;
2578                     mBatteryStatsService.scheduleWriteToDisk();
2579                 }
2580             }
2581         }
2582     }
2583
2584     @Override
2585     public void batteryNeedsCpuUpdate() {
2586         updateCpuStatsNow();
2587     }
2588
2589     @Override
2590     public void batteryPowerChanged(boolean onBattery) {
2591         // When plugging in, update the CPU stats first before changing
2592         // the plug state.
2593         updateCpuStatsNow();
2594         synchronized (this) {
2595             synchronized(mPidsSelfLocked) {
2596                 mOnBattery = DEBUG_POWER ? true : onBattery;
2597             }
2598         }
2599     }
2600
2601     @Override
2602     public void batterySendBroadcast(Intent intent) {
2603         broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
2604                 AppOpsManager.OP_NONE, null, false, false,
2605                 -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
2606     }
2607
2608     /**
2609      * Initialize the application bind args. These are passed to each
2610      * process when the bindApplication() IPC is sent to the process. They're
2611      * lazily setup to make sure the services are running when they're asked for.
2612      */
2613     private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2614         if (mAppBindArgs == null) {
2615             mAppBindArgs = new HashMap<>();
2616
2617             // Isolated processes won't get this optimization, so that we don't
2618             // violate the rules about which services they have access to.
2619             if (!isolated) {
2620                 // Setup the application init args
2621                 mAppBindArgs.put("package", ServiceManager.getService("package"));
2622                 mAppBindArgs.put("window", ServiceManager.getService("window"));
2623                 mAppBindArgs.put(Context.ALARM_SERVICE,
2624                         ServiceManager.getService(Context.ALARM_SERVICE));
2625             }
2626         }
2627         return mAppBindArgs;
2628     }
2629
2630     final void setFocusedActivityLocked(ActivityRecord r, String reason) {
2631         if (r != null && mFocusedActivity != r) {
2632             if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: r=" + r);
2633             ActivityRecord last = mFocusedActivity;
2634             mFocusedActivity = r;
2635             if (r.task.taskType != ActivityRecord.HOME_ACTIVITY_TYPE
2636                     && r.task.taskType != ActivityRecord.RECENTS_ACTIVITY_TYPE) {
2637                 if (mCurAppTimeTracker != r.appTimeTracker) {
2638                     // We are switching app tracking.  Complete the current one.
2639                     if (mCurAppTimeTracker != null) {
2640                         mCurAppTimeTracker.stop();
2641                         mHandler.obtainMessage(REPORT_TIME_TRACKER_MSG,
2642                                 mCurAppTimeTracker).sendToTarget();
2643                         mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
2644                         mCurAppTimeTracker = null;
2645                     }
2646                     if (r.appTimeTracker != null) {
2647                         mCurAppTimeTracker = r.appTimeTracker;
2648                         startTimeTrackingFocusedActivityLocked();
2649                     }
2650                 } else {
2651                     startTimeTrackingFocusedActivityLocked();
2652                 }
2653             } else {
2654                 r.appTimeTracker = null;
2655             }
2656             if (r.task != null && r.task.voiceInteractor != null) {
2657                 startRunningVoiceLocked(r.task.voiceSession, r.info.applicationInfo.uid);
2658             } else {
2659                 finishRunningVoiceLocked();
2660                 if (last != null && last.task.voiceSession != null) {
2661                     // We had been in a voice interaction session, but now focused has
2662                     // move to something different.  Just finish the session, we can't
2663                     // return to it and retain the proper state and synchronization with
2664                     // the voice interaction service.
2665                     finishVoiceTask(last.task.voiceSession);
2666                 }
2667             }
2668             if (mStackSupervisor.setFocusedStack(r, reason + " setFocusedActivity")) {
2669                 mWindowManager.setFocusedApp(r.appToken, true);
2670             }
2671             applyUpdateLockStateLocked(r);
2672             if (mFocusedActivity.userId != mLastFocusedUserId) {
2673                 mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2674                 mHandler.sendMessage(mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG,
2675                         mFocusedActivity.userId, 0));
2676                 mLastFocusedUserId = mFocusedActivity.userId;
2677             }
2678         }
2679         EventLog.writeEvent(EventLogTags.AM_FOCUSED_ACTIVITY,
2680                 mFocusedActivity == null ? -1 : mFocusedActivity.userId,
2681                 mFocusedActivity == null ? "NULL" : mFocusedActivity.shortComponentName);
2682     }
2683
2684     final void clearFocusedActivity(ActivityRecord r) {
2685         if (mFocusedActivity == r) {
2686             ActivityStack stack = mStackSupervisor.getFocusedStack();
2687             if (stack != null) {
2688                 ActivityRecord top = stack.topActivity();
2689                 if (top != null && top.userId != mLastFocusedUserId) {
2690                     mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2691                     mHandler.sendMessage(mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG,
2692                                     top.userId, 0));
2693                     mLastFocusedUserId = top.userId;
2694                 }
2695             }
2696             mFocusedActivity = null;
2697             EventLog.writeEvent(EventLogTags.AM_FOCUSED_ACTIVITY, -1, "NULL");
2698         }
2699     }
2700
2701     @Override
2702     public void setFocusedStack(int stackId) {
2703         if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
2704         synchronized (ActivityManagerService.this) {
2705             ActivityStack stack = mStackSupervisor.getStack(stackId);
2706             if (stack != null) {
2707                 ActivityRecord r = stack.topRunningActivityLocked(null);
2708                 if (r != null) {
2709                     setFocusedActivityLocked(r, "setFocusedStack");
2710                     mStackSupervisor.resumeTopActivitiesLocked(stack, null, null);
2711                 }
2712             }
2713         }
2714     }
2715
2716     /** Sets the task stack listener that gets callbacks when a task stack changes. */
2717     @Override
2718     public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
2719         synchronized (ActivityManagerService.this) {
2720             if (listener != null) {
2721                 mTaskStackListeners.register(listener);
2722             }
2723         }
2724     }
2725
2726     @Override
2727     public void notifyActivityDrawn(IBinder token) {
2728         if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
2729         synchronized (this) {
2730             ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
2731             if (r != null) {
2732                 r.task.stack.notifyActivityDrawnLocked(r);
2733             }
2734         }
2735     }
2736
2737     final void applyUpdateLockStateLocked(ActivityRecord r) {
2738         // Modifications to the UpdateLock state are done on our handler, outside
2739         // the activity manager's locks.  The new state is determined based on the
2740         // state *now* of the relevant activity record.  The object is passed to
2741         // the handler solely for logging detail, not to be consulted/modified.
2742         final boolean nextState = r != null && r.immersive;
2743         mHandler.sendMessage(
2744                 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2745     }
2746
2747     final void showAskCompatModeDialogLocked(ActivityRecord r) {
2748         Message msg = Message.obtain();
2749         msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2750         msg.obj = r.task.askedCompatMode ? null : r;
2751         mUiHandler.sendMessage(msg);
2752     }
2753
2754     private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2755             String what, Object obj, ProcessRecord srcApp) {
2756         app.lastActivityTime = now;
2757
2758         if (app.activities.size() > 0) {
2759             // Don't want to touch dependent processes that are hosting activities.
2760             return index;
2761         }
2762
2763         int lrui = mLruProcesses.lastIndexOf(app);
2764         if (lrui < 0) {
2765             Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2766                     + what + " " + obj + " from " + srcApp);
2767             return index;
2768         }
2769
2770         if (lrui >= index) {
2771             // Don't want to cause this to move dependent processes *back* in the
2772             // list as if they were less frequently used.
2773             return index;
2774         }
2775
2776         if (lrui >= mLruProcessActivityStart) {
2777             // Don't want to touch dependent processes that are hosting activities.
2778             return index;
2779         }
2780
2781         mLruProcesses.remove(lrui);
2782         if (index > 0) {
2783             index--;
2784         }
2785         if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
2786                 + " in LRU list: " + app);
2787         mLruProcesses.add(index, app);
2788         return index;
2789     }
2790
2791     private static void killProcessGroup(int uid, int pid) {
2792         Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
2793         Process.killProcessGroup(uid, pid);
2794         Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
2795     }
2796
2797     final void removeLruProcessLocked(ProcessRecord app) {
2798         int lrui = mLruProcesses.lastIndexOf(app);
2799         if (lrui >= 0) {
2800             if (!app.killed) {
2801                 Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
2802                 Process.killProcessQuiet(app.pid);
2803                 killProcessGroup(app.info.uid, app.pid);
2804             }
2805             if (lrui <= mLruProcessActivityStart) {
2806                 mLruProcessActivityStart--;
2807             }
2808             if (lrui <= mLruProcessServiceStart) {
2809                 mLruProcessServiceStart--;
2810             }
2811             mLruProcesses.remove(lrui);
2812         }
2813     }
2814
2815     final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2816             ProcessRecord client) {
2817         final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2818                 || app.treatLikeActivity;
2819         final boolean hasService = false; // not impl yet. app.services.size() > 0;
2820         if (!activityChange && hasActivity) {
2821             // The process has activities, so we are only allowing activity-based adjustments
2822             // to move it.  It should be kept in the front of the list with other
2823             // processes that have activities, and we don't want those to change their
2824             // order except due to activity operations.
2825             return;
2826         }
2827
2828         mLruSeq++;
2829         final long now = SystemClock.uptimeMillis();
2830         app.lastActivityTime = now;
2831
2832         // First a quick reject: if the app is already at the position we will
2833         // put it, then there is nothing to do.
2834         if (hasActivity) {
2835             final int N = mLruProcesses.size();
2836             if (N > 0 && mLruProcesses.get(N-1) == app) {
2837                 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
2838                 return;
2839             }
2840         } else {
2841             if (mLruProcessServiceStart > 0
2842                     && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2843                 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
2844                 return;
2845             }
2846         }
2847
2848         int lrui = mLruProcesses.lastIndexOf(app);
2849
2850         if (app.persistent && lrui >= 0) {
2851             // We don't care about the position of persistent processes, as long as
2852             // they are in the list.
2853             if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
2854             return;
2855         }
2856
2857         /* In progress: compute new position first, so we can avoid doing work
2858            if the process is not actually going to move.  Not yet working.
2859         int addIndex;
2860         int nextIndex;
2861         boolean inActivity = false, inService = false;
2862         if (hasActivity) {
2863             // Process has activities, put it at the very tipsy-top.
2864             addIndex = mLruProcesses.size();
2865             nextIndex = mLruProcessServiceStart;
2866             inActivity = true;
2867         } else if (hasService) {
2868             // Process has services, put it at the top of the service list.
2869             addIndex = mLruProcessActivityStart;
2870             nextIndex = mLruProcessServiceStart;
2871             inActivity = true;
2872             inService = true;
2873         } else  {
2874             // Process not otherwise of interest, it goes to the top of the non-service area.
2875             addIndex = mLruProcessServiceStart;
2876             if (client != null) {
2877                 int clientIndex = mLruProcesses.lastIndexOf(client);
2878                 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2879                         + app);
2880                 if (clientIndex >= 0 && addIndex > clientIndex) {
2881                     addIndex = clientIndex;
2882                 }
2883             }
2884             nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2885         }
2886
2887         Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2888                 + mLruProcessActivityStart + "): " + app);
2889         */
2890
2891         if (lrui >= 0) {
2892             if (lrui < mLruProcessActivityStart) {
2893                 mLruProcessActivityStart--;
2894             }
2895             if (lrui < mLruProcessServiceStart) {
2896                 mLruProcessServiceStart--;
2897             }
2898             /*
2899             if (addIndex > lrui) {
2900                 addIndex--;
2901             }
2902             if (nextIndex > lrui) {
2903                 nextIndex--;
2904             }
2905             */
2906             mLruProcesses.remove(lrui);
2907         }
2908
2909         /*
2910         mLruProcesses.add(addIndex, app);
2911         if (inActivity) {
2912             mLruProcessActivityStart++;
2913         }
2914         if (inService) {
2915             mLruProcessActivityStart++;
2916         }
2917         */
2918
2919         int nextIndex;
2920         if (hasActivity) {
2921             final int N = mLruProcesses.size();
2922             if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
2923                 // Process doesn't have activities, but has clients with
2924                 // activities...  move it up, but one below the top (the top
2925                 // should always have a real activity).
2926                 if (DEBUG_LRU) Slog.d(TAG_LRU,
2927                         "Adding to second-top of LRU activity list: " + app);
2928                 mLruProcesses.add(N - 1, app);
2929                 // To keep it from spamming the LRU list (by making a bunch of clients),
2930                 // we will push down any other entries owned by the app.
2931                 final int uid = app.info.uid;
2932                 for (int i = N - 2; i > mLruProcessActivityStart; i--) {
2933                     ProcessRecord subProc = mLruProcesses.get(i);
2934                     if (subProc.info.uid == uid) {
2935                         // We want to push this one down the list.  If the process after
2936                         // it is for the same uid, however, don't do so, because we don't
2937                         // want them internally to be re-ordered.
2938                         if (mLruProcesses.get(i - 1).info.uid != uid) {
2939                             if (DEBUG_LRU) Slog.d(TAG_LRU,
2940                                     "Pushing uid " + uid + " swapping at " + i + ": "
2941                                     + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
2942                             ProcessRecord tmp = mLruProcesses.get(i);
2943                             mLruProcesses.set(i, mLruProcesses.get(i - 1));
2944                             mLruProcesses.set(i - 1, tmp);
2945                             i--;
2946                         }
2947                     } else {
2948                         // A gap, we can stop here.
2949                         break;
2950                     }
2951                 }
2952             } else {
2953                 // Process has activities, put it at the very tipsy-top.
2954                 if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
2955                 mLruProcesses.add(app);
2956             }
2957             nextIndex = mLruProcessServiceStart;
2958         } else if (hasService) {
2959             // Process has services, put it at the top of the service list.
2960             if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
2961             mLruProcesses.add(mLruProcessActivityStart, app);
2962             nextIndex = mLruProcessServiceStart;
2963             mLruProcessActivityStart++;
2964         } else  {
2965             // Process not otherwise of interest, it goes to the top of the non-service area.
2966             int index = mLruProcessServiceStart;
2967             if (client != null) {
2968                 // If there is a client, don't allow the process to be moved up higher
2969                 // in the list than that client.
2970                 int clientIndex = mLruProcesses.lastIndexOf(client);
2971                 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
2972                         + " when updating " + app);
2973                 if (clientIndex <= lrui) {
2974                     // Don't allow the client index restriction to push it down farther in the
2975                     // list than it already is.
2976                     clientIndex = lrui;
2977                 }
2978                 if (clientIndex >= 0 && index > clientIndex) {
2979                     index = clientIndex;
2980                 }
2981             }
2982             if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
2983             mLruProcesses.add(index, app);
2984             nextIndex = index-1;
2985             mLruProcessActivityStart++;
2986             mLruProcessServiceStart++;
2987         }
2988
2989         // If the app is currently using a content provider or service,
2990         // bump those processes as well.
2991         for (int j=app.connections.size()-1; j>=0; j--) {
2992             ConnectionRecord cr = app.connections.valueAt(j);
2993             if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2994                     && cr.binding.service.app != null
2995                     && cr.binding.service.app.lruSeq != mLruSeq
2996                     && !cr.binding.service.app.persistent) {
2997                 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2998                         "service connection", cr, app);
2999             }
3000         }
3001         for (int j=app.conProviders.size()-1; j>=0; j--) {
3002             ContentProviderRecord cpr = app.conProviders.get(j).provider;
3003             if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
3004                 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
3005                         "provider reference", cpr, app);
3006             }
3007         }
3008     }
3009
3010     final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
3011         if (uid == Process.SYSTEM_UID) {
3012             // The system gets to run in any process.  If there are multiple
3013             // processes with the same uid, just pick the first (this
3014             // should never happen).
3015             SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
3016             if (procs == null) return null;
3017             final int procCount = procs.size();
3018             for (int i = 0; i < procCount; i++) {
3019                 final int procUid = procs.keyAt(i);
3020                 if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
3021                     // Don't use an app process or different user process for system component.
3022                     continue;
3023                 }
3024                 return procs.valueAt(i);
3025             }
3026         }
3027         ProcessRecord proc = mProcessNames.get(processName, uid);
3028         if (false && proc != null && !keepIfLarge
3029                 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3030                 && proc.lastCachedPss >= 4000) {
3031             // Turn this condition on to cause killing to happen regularly, for testing.
3032             if (proc.baseProcessTracker != null) {
3033                 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3034             }
3035             proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3036         } else if (proc != null && !keepIfLarge
3037                 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3038                 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3039             if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3040             if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3041                 if (proc.baseProcessTracker != null) {
3042                     proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3043                 }
3044                 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3045             }
3046         }
3047         return proc;
3048     }
3049
3050     void ensurePackageDexOpt(String packageName) {
3051         IPackageManager pm = AppGlobals.getPackageManager();
3052         try {
3053             if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) {
3054                 mDidDexOpt = true;
3055             }
3056         } catch (RemoteException e) {
3057         }
3058     }
3059
3060     boolean isNextTransitionForward() {
3061         int transit = mWindowManager.getPendingAppTransition();
3062         return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
3063                 || transit == AppTransition.TRANSIT_TASK_OPEN
3064                 || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
3065     }
3066
3067     int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3068             String processName, String abiOverride, int uid, Runnable crashHandler) {
3069         synchronized(this) {
3070             ApplicationInfo info = new ApplicationInfo();
3071             // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3072             // For isolated processes, the former contains the parent's uid and the latter the
3073             // actual uid of the isolated process.
3074             // In the special case introduced by this method (which is, starting an isolated
3075             // process directly from the SystemServer without an actual parent app process) the
3076             // closest thing to a parent's uid is SYSTEM_UID.
3077             // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3078             // the |isolated| logic in the ProcessRecord constructor.
3079             info.uid = Process.SYSTEM_UID;
3080             info.processName = processName;
3081             info.className = entryPoint;
3082             info.packageName = "android";
3083             ProcessRecord proc = startProcessLocked(processName, info /* info */,
3084                     false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
3085                     null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3086                     uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3087                     crashHandler);
3088             return proc != null ? proc.pid : 0;
3089         }
3090     }
3091
3092     final ProcessRecord startProcessLocked(String processName,
3093             ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3094             String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3095             boolean isolated, boolean keepIfLarge) {
3096         return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3097                 hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3098                 null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3099                 null /* crashHandler */);
3100     }
3101
3102     final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3103             boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3104             boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3105             String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3106         long startTime = SystemClock.elapsedRealtime();
3107         ProcessRecord app;
3108         if (!isolated) {
3109             app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3110             checkTime(startTime, "startProcess: after getProcessRecord");
3111
3112             if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3113                 // If we are in the background, then check to see if this process
3114                 // is bad.  If so, we will just silently fail.
3115                 if (mBadProcesses.get(info.processName, info.uid) != null) {
3116                     if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3117                             + "/" + info.processName);
3118                     return null;
3119                 }
3120             } else {
3121                 // When the user is explicitly starting a process, then clear its
3122                 // crash count so that we won't make it bad until they see at
3123                 // least one crash dialog again, and make the process good again
3124                 // if it had been bad.
3125                 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3126                         + "/" + info.processName);
3127                 mProcessCrashTimes.remove(info.processName, info.uid);
3128                 if (mBadProcesses.get(info.processName, info.uid) != null) {
3129                     EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3130                             UserHandle.getUserId(info.uid), info.uid,
3131                             info.processName);
3132                     mBadProcesses.remove(info.processName, info.uid);
3133                     if (app != null) {
3134                         app.bad = false;
3135                     }
3136                 }
3137             }
3138         } else {
3139             // If this is an isolated process, it can't re-use an existing process.
3140             app = null;
3141         }
3142
3143         // app launch boost for big.little configurations
3144         // use cpusets to migrate freshly launched tasks to big cores
3145         synchronized(ActivityManagerService.this) {
3146             nativeMigrateToBoost();
3147             mIsBoosted = true;
3148             mBoostStartTime = SystemClock.uptimeMillis();
3149             Message msg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
3150             mHandler.sendMessageDelayed(msg, APP_BOOST_MESSAGE_DELAY);
3151         }
3152
3153         // We don't have to do anything more if:
3154         // (1) There is an existing application record; and
3155         // (2) The caller doesn't think it is dead, OR there is no thread
3156         //     object attached to it so we know it couldn't have crashed; and
3157         // (3) There is a pid assigned to it, so it is either starting or
3158         //     already running.
3159         if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3160                 + " app=" + app + " knownToBeDead=" + knownToBeDead
3161                 + " thread=" + (app != null ? app.thread : null)
3162                 + " pid=" + (app != null ? app.pid : -1));
3163         if (app != null && app.pid > 0) {
3164             if (!knownToBeDead || app.thread == null) {
3165                 // We already have the app running, or are waiting for it to
3166                 // come up (we have a pid but not yet its thread), so keep it.
3167                 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3168                 // If this is a new package in the process, add the package to the list
3169                 app.addPackage(info.packageName, info.versionCode, mProcessStats);
3170                 checkTime(startTime, "startProcess: done, added package to proc");
3171                 return app;
3172             }
3173
3174             // An application record is attached to a previous process,
3175             // clean it up now.
3176             if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3177             checkTime(startTime, "startProcess: bad proc running, killing");
3178             killProcessGroup(app.info.uid, app.pid);
3179             handleAppDiedLocked(app, true, true);
3180             checkTime(startTime, "startProcess: done killing old proc");
3181         }
3182
3183         String hostingNameStr = hostingName != null
3184                 ? hostingName.flattenToShortString() : null;
3185
3186         if (app == null) {
3187             checkTime(startTime, "startProcess: creating new process record");
3188             app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3189             if (app == null) {
3190                 Slog.w(TAG, "Failed making new process record for "
3191                         + processName + "/" + info.uid + " isolated=" + isolated);
3192                 return null;
3193             }
3194             app.crashHandler = crashHandler;
3195             checkTime(startTime, "startProcess: done creating new process record");
3196         } else {
3197             // If this is a new package in the process, add the package to the list
3198             app.addPackage(info.packageName, info.versionCode, mProcessStats);
3199             checkTime(startTime, "startProcess: added package to existing proc");
3200         }
3201
3202         // If the system is not ready yet, then hold off on starting this
3203         // process until it is.
3204         if (!mProcessesReady
3205                 && !isAllowedWhileBooting(info)
3206                 && !allowWhileBooting) {
3207             if (!mProcessesOnHold.contains(app)) {
3208                 mProcessesOnHold.add(app);
3209             }
3210             if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3211                     "System not ready, putting on hold: " + app);
3212             checkTime(startTime, "startProcess: returning with proc on hold");
3213             return app;
3214         }
3215
3216         checkTime(startTime, "startProcess: stepping in to startProcess");
3217         startProcessLocked(
3218                 app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3219         checkTime(startTime, "startProcess: done starting proc!");
3220         return (app.pid != 0) ? app : null;
3221     }
3222
3223     boolean isAllowedWhileBooting(ApplicationInfo ai) {
3224         return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3225     }
3226
3227     private final void startProcessLocked(ProcessRecord app,
3228             String hostingType, String hostingNameStr) {
3229         startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3230                 null /* entryPoint */, null /* entryPointArgs */);
3231     }
3232
3233     private final void startProcessLocked(ProcessRecord app, String hostingType,
3234             String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3235         long startTime = SystemClock.elapsedRealtime();
3236         if (app.pid > 0 && app.pid != MY_PID) {
3237             checkTime(startTime, "startProcess: removing from pids map");
3238             synchronized (mPidsSelfLocked) {
3239                 mPidsSelfLocked.remove(app.pid);
3240                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3241             }
3242             checkTime(startTime, "startProcess: done removing from pids map");
3243             app.setPid(0);
3244         }
3245
3246         if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3247                 "startProcessLocked removing on hold: " + app);
3248         mProcessesOnHold.remove(app);
3249
3250         checkTime(startTime, "startProcess: starting to update cpu stats");
3251         updateCpuStats();
3252         checkTime(startTime, "startProcess: done updating cpu stats");
3253
3254         try {
3255             try {
3256                 if (AppGlobals.getPackageManager().isPackageFrozen(app.info.packageName)) {
3257                     // This is caught below as if we had failed to fork zygote
3258                     throw new RuntimeException("Package " + app.info.packageName + " is frozen!");
3259                 }
3260             } catch (RemoteException e) {
3261                 throw e.rethrowAsRuntimeException();
3262             }
3263
3264             int uid = app.uid;
3265             int[] gids = null;
3266             int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3267             if (!app.isolated) {
3268                 int[] permGids = null;
3269                 try {
3270                     checkTime(startTime, "startProcess: getting gids from package manager");
3271                     final IPackageManager pm = AppGlobals.getPackageManager();
3272                     permGids = pm.getPackageGids(app.info.packageName, app.userId);
3273                     MountServiceInternal mountServiceInternal = LocalServices.getService(
3274                             MountServiceInternal.class);
3275                     mountExternal = mountServiceInternal.getExternalStorageMountMode(uid,
3276                             app.info.packageName);
3277                 } catch (RemoteException e) {
3278                     throw e.rethrowAsRuntimeException();
3279                 }
3280
3281                 /*
3282                  * Add shared application and profile GIDs so applications can share some
3283                  * resources like shared libraries and access user-wide resources
3284                  */
3285                 if (ArrayUtils.isEmpty(permGids)) {
3286                     gids = new int[2];
3287                 } else {
3288                     gids = new int[permGids.length + 2];
3289                     System.arraycopy(permGids, 0, gids, 2, permGids.length);
3290                 }
3291                 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3292                 gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3293             }
3294             checkTime(startTime, "startProcess: building args");
3295             if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3296                 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3297                         && mTopComponent != null
3298                         && app.processName.equals(mTopComponent.getPackageName())) {
3299                     uid = 0;
3300                 }
3301                 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3302                         && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3303                     uid = 0;
3304                 }
3305             }
3306             int debugFlags = 0;
3307             if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3308                 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3309                 // Also turn on CheckJNI for debuggable apps. It's quite
3310                 // awkward to turn on otherwise.
3311                 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3312             }
3313             // Run the app in safe mode if its manifest requests so or the
3314             // system is booted in safe mode.
3315             if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3316                 mSafeMode == true) {
3317                 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3318             }
3319             if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3320                 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3321             }
3322             String jitDebugProperty = SystemProperties.get("debug.usejit");
3323             if ("true".equals(jitDebugProperty)) {
3324                 debugFlags |= Zygote.DEBUG_ENABLE_JIT;
3325             } else if (!"false".equals(jitDebugProperty)) {
3326                 // If we didn't force disable by setting false, defer to the dalvik vm options.
3327                 if ("true".equals(SystemProperties.get("dalvik.vm.usejit"))) {
3328                     debugFlags |= Zygote.DEBUG_ENABLE_JIT;
3329                 }
3330             }
3331             String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3332             if ("true".equals(genDebugInfoProperty)) {
3333                 debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3334             }
3335             if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3336                 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3337             }
3338             if ("1".equals(SystemProperties.get("debug.assert"))) {
3339                 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3340             }
3341
3342             String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3343             if (requiredAbi == null) {
3344                 requiredAbi = Build.SUPPORTED_ABIS[0];
3345             }
3346
3347             String instructionSet = null;
3348             if (app.info.primaryCpuAbi != null) {
3349                 instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3350             }
3351
3352             app.gids = gids;
3353             app.requiredAbi = requiredAbi;
3354             app.instructionSet = instructionSet;
3355
3356             // Start the process.  It will either succeed and return a result containing
3357             // the PID of the new process, or else throw a RuntimeException.
3358             boolean isActivityProcess = (entryPoint == null);
3359             if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3360             Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3361                     app.processName);
3362             checkTime(startTime, "startProcess: asking zygote to start proc");
3363             Process.ProcessStartResult startResult = Process.start(entryPoint,
3364                     app.processName, uid, uid, gids, debugFlags, mountExternal,
3365                     app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3366                     app.info.dataDir, entryPointArgs);
3367             checkTime(startTime, "startProcess: returned from zygote!");
3368             Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3369
3370             if (app.isolated) {
3371                 mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3372             }
3373             mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3374             checkTime(startTime, "startProcess: done updating battery stats");
3375
3376             EventLog.writeEvent(EventLogTags.AM_PROC_START,
3377                     UserHandle.getUserId(uid), startResult.pid, uid,
3378                     app.processName, hostingType,
3379                     hostingNameStr != null ? hostingNameStr : "");
3380
3381             if (app.persistent) {
3382                 Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3383             }
3384
3385             checkTime(startTime, "startProcess: building log message");
3386             StringBuilder buf = mStringBuilder;
3387             buf.setLength(0);
3388             buf.append("Start proc ");
3389             buf.append(startResult.pid);
3390             buf.append(':');
3391             buf.append(app.processName);
3392             buf.append('/');
3393             UserHandle.formatUid(buf, uid);
3394             if (!isActivityProcess) {
3395                 buf.append(" [");
3396                 buf.append(entryPoint);
3397                 buf.append("]");
3398             }
3399             buf.append(" for ");
3400             buf.append(hostingType);
3401             if (hostingNameStr != null) {
3402                 buf.append(" ");
3403                 buf.append(hostingNameStr);
3404             }
3405             Slog.i(TAG, buf.toString());
3406             app.setPid(startResult.pid);
3407             app.usingWrapper = startResult.usingWrapper;
3408             app.removed = false;
3409             app.killed = false;
3410             app.killedByAm = false;
3411             checkTime(startTime, "startProcess: starting to update pids map");
3412             synchronized (mPidsSelfLocked) {
3413                 this.mPidsSelfLocked.put(startResult.pid, app);
3414                 if (isActivityProcess) {
3415                     Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3416                     msg.obj = app;
3417                     mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3418                             ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3419                 }
3420             }
3421             checkTime(startTime, "startProcess: done updating pids map");
3422         } catch (RuntimeException e) {
3423             // XXX do better error recovery.
3424             app.setPid(0);
3425             mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3426             if (app.isolated) {
3427                 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3428             }
3429             Slog.e(TAG, "Failure starting process " + app.processName, e);
3430         }
3431     }
3432
3433     void updateUsageStats(ActivityRecord component, boolean resumed) {
3434         if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
3435                 "updateUsageStats: comp=" + component + "res=" + resumed);
3436         final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3437         if (resumed) {
3438             if (mUsageStatsService != null) {
3439                 mUsageStatsService.reportEvent(component.realActivity, component.userId,
3440                         UsageEvents.Event.MOVE_TO_FOREGROUND);
3441             }
3442             synchronized (stats) {
3443                 stats.noteActivityResumedLocked(component.app.uid);
3444             }
3445         } else {
3446             if (mUsageStatsService != null) {
3447                 mUsageStatsService.reportEvent(component.realActivity, component.userId,
3448                         UsageEvents.Event.MOVE_TO_BACKGROUND);
3449             }
3450             synchronized (stats) {
3451                 stats.noteActivityPausedLocked(component.app.uid);
3452             }
3453         }
3454     }
3455
3456     Intent getHomeIntent() {
3457         Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3458         intent.setComponent(mTopComponent);
3459         if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3460             intent.addCategory(Intent.CATEGORY_HOME);
3461         }
3462         return intent;
3463     }
3464
3465     boolean startHomeActivityLocked(int userId, String reason) {
3466         if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3467                 && mTopAction == null) {
3468             // We are running in factory test mode, but unable to find
3469             // the factory test app, so just sit around displaying the
3470             // error message and don't try to start anything.
3471             return false;
3472         }
3473         Intent intent = getHomeIntent();
3474         ActivityInfo aInfo =
3475             resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3476         if (aInfo != null) {
3477             intent.setComponent(new ComponentName(
3478                     aInfo.applicationInfo.packageName, aInfo.name));
3479             // Don't do this if the home app is currently being
3480             // instrumented.
3481             aInfo = new ActivityInfo(aInfo);
3482             aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3483             ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3484                     aInfo.applicationInfo.uid, true);
3485             if (app == null || app.instrumentationClass == null) {
3486                 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3487                 mStackSupervisor.startHomeActivity(intent, aInfo, reason);
3488             }
3489         }
3490
3491         return true;
3492     }
3493
3494     private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3495         ActivityInfo ai = null;
3496         ComponentName comp = intent.getComponent();
3497         try {
3498             if (comp != null) {
3499                 // Factory test.
3500                 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3501             } else {
3502                 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3503                         intent,
3504                         intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3505                         flags, userId);
3506
3507                 if (info != null) {
3508                     ai = info.activityInfo;
3509                 }
3510             }
3511         } catch (RemoteException e) {
3512             // ignore
3513         }
3514
3515         return ai;
3516     }
3517
3518     /**
3519      * Starts the "new version setup screen" if appropriate.
3520      */
3521     void startSetupActivityLocked() {
3522         // Only do this once per boot.
3523         if (mCheckedForSetup) {
3524             return;
3525         }
3526
3527         // We will show this screen if the current one is a different
3528         // version than the last one shown, and we are not running in
3529         // low-level factory test mode.
3530         final ContentResolver resolver = mContext.getContentResolver();
3531         if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3532                 Settings.Global.getInt(resolver,
3533                         Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3534             mCheckedForSetup = true;
3535
3536             // See if we should be showing the platform update setup UI.
3537             Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3538             List<ResolveInfo> ris = mContext.getPackageManager()
3539                     .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3540
3541             // We don't allow third party apps to replace this.
3542             ResolveInfo ri = null;
3543             for (int i=0; ris != null && i<ris.size(); i++) {
3544                 if ((ris.get(i).activityInfo.applicationInfo.flags
3545                         & ApplicationInfo.FLAG_SYSTEM) != 0) {
3546                     ri = ris.get(i);
3547                     break;
3548                 }
3549             }
3550
3551             if (ri != null) {
3552                 String vers = ri.activityInfo.metaData != null
3553                         ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3554                         : null;
3555                 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3556                     vers = ri.activityInfo.applicationInfo.metaData.getString(
3557                             Intent.METADATA_SETUP_VERSION);
3558                 }
3559                 String lastVers = Settings.Secure.getString(
3560                         resolver, Settings.Secure.LAST_SETUP_SHOWN);
3561                 if (vers != null && !vers.equals(lastVers)) {
3562                     intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3563                     intent.setComponent(new ComponentName(
3564                             ri.activityInfo.packageName, ri.activityInfo.name));
3565                     mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3566                             null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, false,
3567                             null, null, null);
3568                 }
3569             }
3570         }
3571     }
3572
3573     CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3574         return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3575     }
3576
3577     void enforceNotIsolatedCaller(String caller) {
3578         if (UserHandle.isIsolated(Binder.getCallingUid())) {
3579             throw new SecurityException("Isolated process not allowed to call " + caller);
3580         }
3581     }
3582
3583     void enforceShellRestriction(String restriction, int userHandle) {
3584         if (Binder.getCallingUid() == Process.SHELL_UID) {
3585             if (userHandle < 0
3586                     || mUserManager.hasUserRestriction(restriction, userHandle)) {
3587                 throw new SecurityException("Shell does not have permission to access user "
3588                         + userHandle);
3589             }
3590         }
3591     }
3592
3593     @Override
3594     public int getFrontActivityScreenCompatMode() {
3595         enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3596         synchronized (this) {
3597             return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3598         }
3599     }
3600
3601     @Override
3602     public void setFrontActivityScreenCompatMode(int mode) {
3603         enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3604                 "setFrontActivityScreenCompatMode");
3605         synchronized (this) {
3606             mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3607         }
3608     }
3609
3610     @Override
3611     public int getPackageScreenCompatMode(String packageName) {
3612         enforceNotIsolatedCaller("getPackageScreenCompatMode");
3613         synchronized (this) {
3614             return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3615         }
3616     }
3617
3618     @Override
3619     public void setPackageScreenCompatMode(String packageName, int mode) {
3620         enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3621                 "setPackageScreenCompatMode");
3622         synchronized (this) {
3623             mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3624         }
3625     }
3626
3627     @Override
3628     public boolean getPackageAskScreenCompat(String packageName) {
3629         enforceNotIsolatedCaller("getPackageAskScreenCompat");
3630         synchronized (this) {
3631             return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3632         }
3633     }
3634
3635     @Override
3636     public void setPackageAskScreenCompat(String packageName, boolean ask) {
3637         enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3638                 "setPackageAskScreenCompat");
3639         synchronized (this) {
3640             mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3641         }
3642     }
3643
3644     private boolean hasUsageStatsPermission(String callingPackage) {
3645         final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
3646                 Binder.getCallingUid(), callingPackage);
3647         if (mode == AppOpsManager.MODE_DEFAULT) {
3648             return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
3649                     == PackageManager.PERMISSION_GRANTED;
3650         }
3651         return mode == AppOpsManager.MODE_ALLOWED;
3652     }
3653
3654     @Override
3655     public int getPackageProcessState(String packageName, String callingPackage) {
3656         if (!hasUsageStatsPermission(callingPackage)) {
3657             enforceCallingPermission(android.Manifest.permission.GET_PACKAGE_IMPORTANCE,
3658                     "getPackageProcessState");
3659         }
3660
3661         int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
3662         synchronized (this) {
3663             for (int i=mLruProcesses.size()-1; i>=0; i--) {
3664                 final ProcessRecord proc = mLruProcesses.get(i);
3665                 if (procState == ActivityManager.PROCESS_STATE_NONEXISTENT
3666                         || procState > proc.setProcState) {
3667                     boolean found = false;
3668                     for (int j=proc.pkgList.size()-1; j>=0 && !found; j--) {
3669                         if (proc.pkgList.keyAt(j).equals(packageName)) {
3670                             procState = proc.setProcState;
3671                             found = true;
3672                         }
3673                     }
3674                     if (proc.pkgDeps != null && !found) {
3675                         for (int j=proc.pkgDeps.size()-1; j>=0; j--) {
3676                             if (proc.pkgDeps.valueAt(j).equals(packageName)) {
3677                                 procState = proc.setProcState;
3678                                 break;
3679                             }
3680                         }
3681                     }
3682                 }
3683             }
3684         }
3685         return procState;
3686     }
3687
3688     @Override
3689     public boolean setProcessMemoryTrimLevel(String process, int userId, int level) {
3690         synchronized (this) {
3691             final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
3692             if (app == null) {
3693                 return false;
3694             }
3695             if (app.trimMemoryLevel < level && app.thread != null &&
3696                     (level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
3697                             app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND)) {
3698                 try {
3699                     app.thread.scheduleTrimMemory(level);
3700                     app.trimMemoryLevel = level;
3701                     return true;
3702                 } catch (RemoteException e) {
3703                     // Fallthrough to failure case.
3704                 }
3705             }
3706         }
3707         return false;
3708     }
3709
3710     private void dispatchProcessesChanged() {
3711         int N;
3712         synchronized (this) {
3713             N = mPendingProcessChanges.size();
3714             if (mActiveProcessChanges.length < N) {
3715                 mActiveProcessChanges = new ProcessChangeItem[N];
3716             }
3717             mPendingProcessChanges.toArray(mActiveProcessChanges);
3718             mPendingProcessChanges.clear();
3719             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
3720                     "*** Delivering " + N + " process changes");
3721         }
3722
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                     for (int j=0; j<N; j++) {
3730                         ProcessChangeItem item = mActiveProcessChanges[j];
3731                         if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3732                             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
3733                                     "ACTIVITIES CHANGED pid=" + item.pid + " uid="
3734                                     + item.uid + ": " + item.foregroundActivities);
3735                             observer.onForegroundActivitiesChanged(item.pid, item.uid,
3736                                     item.foregroundActivities);
3737                         }
3738                         if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3739                             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
3740                                     "PROCSTATE CHANGED pid=" + item.pid + " uid=" + item.uid
3741                                     + ": " + item.processState);
3742                             observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3743                         }
3744                     }
3745                 } catch (RemoteException e) {
3746                 }
3747             }
3748         }
3749         mProcessObservers.finishBroadcast();
3750
3751         synchronized (this) {
3752             for (int j=0; j<N; j++) {
3753                 mAvailProcessChanges.add(mActiveProcessChanges[j]);
3754             }
3755         }
3756     }
3757
3758     private void dispatchProcessDied(int pid, int uid) {
3759         int i = mProcessObservers.beginBroadcast();
3760         while (i > 0) {
3761             i--;
3762             final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3763             if (observer != null) {
3764                 try {
3765                     observer.onProcessDied(pid, uid);
3766                 } catch (RemoteException e) {
3767                 }
3768             }
3769         }
3770         mProcessObservers.finishBroadcast();
3771     }
3772
3773     private void dispatchUidsChanged() {
3774         int N;
3775         synchronized (this) {
3776             N = mPendingUidChanges.size();
3777             if (mActiveUidChanges.length < N) {
3778                 mActiveUidChanges = new UidRecord.ChangeItem[N];
3779             }
3780             for (int i=0; i<N; i++) {
3781                 final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
3782                 mActiveUidChanges[i] = change;
3783                 change.uidRecord.pendingChange = null;
3784                 change.uidRecord = null;
3785             }
3786             mPendingUidChanges.clear();
3787             if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
3788                     "*** Delivering " + N + " uid changes");
3789         }
3790
3791         if (mLocalPowerManager != null) {
3792             for (int j=0; j<N; j++) {
3793                 UidRecord.ChangeItem item = mActiveUidChanges[j];
3794                 if (item.gone) {
3795                     mLocalPowerManager.uidGone(item.uid);
3796                 } else {
3797                     mLocalPowerManager.updateUidProcState(item.uid, item.processState);
3798                 }
3799             }
3800         }
3801
3802         int i = mUidObservers.beginBroadcast();
3803         while (i > 0) {
3804             i--;
3805             final IUidObserver observer = mUidObservers.getBroadcastItem(i);
3806             if (observer != null) {
3807                 try {
3808                     for (int j=0; j<N; j++) {
3809                         UidRecord.ChangeItem item = mActiveUidChanges[j];
3810                         if (item.gone) {
3811                             if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
3812                                     "UID gone uid=" + item.uid);
3813                             observer.onUidGone(item.uid);
3814                         } else {
3815                             if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
3816                                     "UID CHANGED uid=" + item.uid
3817                                     + ": " + item.processState);
3818                             observer.onUidStateChanged(item.uid, item.processState);
3819                         }
3820                     }
3821                 } catch (RemoteException e) {
3822                 }
3823             }
3824         }
3825         mUidObservers.finishBroadcast();
3826
3827         synchronized (this) {
3828             for (int j=0; j<N; j++) {
3829                 mAvailUidChanges.add(mActiveUidChanges[j]);
3830             }
3831         }
3832     }
3833
3834     @Override
3835     public final int startActivity(IApplicationThread caller, String callingPackage,
3836             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3837             int startFlags, ProfilerInfo profilerInfo, Bundle options) {
3838         return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3839             resultWho, requestCode, startFlags, profilerInfo, options,
3840             UserHandle.getCallingUserId());
3841     }
3842
3843     @Override
3844     public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3845             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3846             int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3847         enforceNotIsolatedCaller("startActivity");
3848         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3849                 false, ALLOW_FULL_ONLY, "startActivity", null);
3850         // TODO: Switch to user app stacks here.
3851         return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3852                 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3853                 profilerInfo, null, null, options, false, userId, null, null);
3854     }
3855
3856     @Override
3857     public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
3858             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3859             int startFlags, ProfilerInfo profilerInfo, Bundle options, boolean ignoreTargetSecurity,
3860             int userId) {
3861
3862         // This is very dangerous -- it allows you to perform a start activity (including
3863         // permission grants) as any app that may launch one of your own activities.  So
3864         // we will only allow this to be done from activities that are part of the core framework,
3865         // and then only when they are running as the system.
3866         final ActivityRecord sourceRecord;
3867         final int targetUid;
3868         final String targetPackage;
3869         synchronized (this) {
3870             if (resultTo == null) {
3871                 throw new SecurityException("Must be called from an activity");
3872             }
3873             sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
3874             if (sourceRecord == null) {
3875                 throw new SecurityException("Called with bad activity token: " + resultTo);
3876             }
3877             if (!sourceRecord.info.packageName.equals("android")) {
3878                 throw new SecurityException(
3879                         "Must be called from an activity that is declared in the android package");
3880             }
3881             if (sourceRecord.app == null) {
3882                 throw new SecurityException("Called without a process attached to activity");
3883             }
3884             if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
3885                 // This is still okay, as long as this activity is running under the
3886                 // uid of the original calling activity.
3887                 if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
3888                     throw new SecurityException(
3889                             "Calling activity in uid " + sourceRecord.app.uid
3890                                     + " must be system uid or original calling uid "
3891                                     + sourceRecord.launchedFromUid);
3892                 }
3893             }
3894             if (ignoreTargetSecurity) {
3895                 if (intent.getComponent() == null) {
3896                     throw new SecurityException(
3897                             "Component must be specified with ignoreTargetSecurity");
3898                 }
3899                 if (intent.getSelector() != null) {
3900                     throw new SecurityException(
3901                             "Selector not allowed with ignoreTargetSecurity");
3902                 }
3903             }
3904             targetUid = sourceRecord.launchedFromUid;
3905             targetPackage = sourceRecord.launchedFromPackage;
3906         }
3907
3908         if (userId == UserHandle.USER_NULL) {
3909             userId = UserHandle.getUserId(sourceRecord.app.uid);
3910         }
3911
3912         // TODO: Switch to user app stacks here.
3913         try {
3914             int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent,
3915                     resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
3916                     null, null, options, ignoreTargetSecurity, userId, null, null);
3917             return ret;
3918         } catch (SecurityException e) {
3919             // XXX need to figure out how to propagate to original app.
3920             // A SecurityException here is generally actually a fault of the original
3921             // calling activity (such as a fairly granting permissions), so propagate it
3922             // back to them.
3923             /*
3924             StringBuilder msg = new StringBuilder();
3925             msg.append("While launching");
3926             msg.append(intent.toString());
3927             msg.append(": ");
3928             msg.append(e.getMessage());
3929             */
3930             throw e;
3931         }
3932     }
3933
3934     @Override
3935     public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3936             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3937             int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3938         enforceNotIsolatedCaller("startActivityAndWait");
3939         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3940                 false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
3941         WaitResult res = new WaitResult();
3942         // TODO: Switch to user app stacks here.
3943         mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3944                 null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
3945                 options, false, userId, null, null);
3946         return res;
3947     }
3948
3949     @Override
3950     public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3951             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3952             int startFlags, Configuration config, Bundle options, int userId) {
3953         enforceNotIsolatedCaller("startActivityWithConfig");
3954         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3955                 false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
3956         // TODO: Switch to user app stacks here.
3957         int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3958                 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3959                 null, null, config, options, false, userId, null, null);
3960         return ret;
3961     }
3962
3963     @Override
3964     public int startActivityIntentSender(IApplicationThread caller, IntentSender intent,
3965             Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho,
3966             int requestCode, int flagsMask, int flagsValues, Bundle options)
3967             throws TransactionTooLargeException {
3968         enforceNotIsolatedCaller("startActivityIntentSender");
3969         // Refuse possible leaked file descriptors
3970         if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3971             throw new IllegalArgumentException("File descriptors passed in Intent");
3972         }
3973
3974         IIntentSender sender = intent.getTarget();
3975         if (!(sender instanceof PendingIntentRecord)) {
3976             throw new IllegalArgumentException("Bad PendingIntent object");
3977         }
3978
3979         PendingIntentRecord pir = (PendingIntentRecord)sender;
3980
3981         synchronized (this) {
3982             // If this is coming from the currently resumed activity, it is
3983             // effectively saying that app switches are allowed at this point.
3984             final ActivityStack stack = getFocusedStack();
3985             if (stack.mResumedActivity != null &&
3986                     stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3987                 mAppSwitchesAllowedTime = 0;
3988             }
3989         }
3990         int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3991                 resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3992         return ret;
3993     }
3994
3995     @Override
3996     public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3997             Intent intent, String resolvedType, IVoiceInteractionSession session,
3998             IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
3999             Bundle options, int userId) {
4000         if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4001                 != PackageManager.PERMISSION_GRANTED) {
4002             String msg = "Permission Denial: startVoiceActivity() from pid="
4003                     + Binder.getCallingPid()
4004                     + ", uid=" + Binder.getCallingUid()
4005                     + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
4006             Slog.w(TAG, msg);
4007             throw new SecurityException(msg);
4008         }
4009         if (session == null || interactor == null) {
4010             throw new NullPointerException("null session or interactor");
4011         }
4012         userId = handleIncomingUser(callingPid, callingUid, userId,
4013                 false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
4014         // TODO: Switch to user app stacks here.
4015         return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
4016                 resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
4017                 null, options, false, userId, null, null);
4018     }
4019
4020     @Override
4021     public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
4022         synchronized (this) {
4023             if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
4024                 if (keepAwake) {
4025                     mVoiceWakeLock.acquire();
4026                 } else {
4027                     mVoiceWakeLock.release();
4028                 }
4029             }
4030         }
4031     }
4032
4033     @Override
4034     public boolean startNextMatchingActivity(IBinder callingActivity,
4035             Intent intent, Bundle options) {
4036         // Refuse possible leaked file descriptors
4037         if (intent != null && intent.hasFileDescriptors() == true) {
4038             throw new IllegalArgumentException("File descriptors passed in Intent");
4039         }
4040
4041         synchronized (this) {
4042             final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4043             if (r == null) {
4044                 ActivityOptions.abort(options);
4045                 return false;
4046             }
4047             if (r.app == null || r.app.thread == null) {
4048                 // The caller is not running...  d'oh!
4049                 ActivityOptions.abort(options);
4050                 return false;
4051             }
4052             intent = new Intent(intent);
4053             // The caller is not allowed to change the data.
4054             intent.setDataAndType(r.intent.getData(), r.intent.getType());
4055             // And we are resetting to find the next component...
4056             intent.setComponent(null);
4057
4058             final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4059
4060             ActivityInfo aInfo = null;
4061             try {
4062                 List<ResolveInfo> resolves =
4063                     AppGlobals.getPackageManager().queryIntentActivities(
4064                             intent, r.resolvedType,
4065                             PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4066                             UserHandle.getCallingUserId());
4067
4068                 // Look for the original activity in the list...
4069                 final int N = resolves != null ? resolves.size() : 0;
4070                 for (int i=0; i<N; i++) {
4071                     ResolveInfo rInfo = resolves.get(i);
4072                     if (rInfo.activityInfo.packageName.equals(r.packageName)
4073                             && rInfo.activityInfo.name.equals(r.info.name)) {
4074                         // We found the current one...  the next matching is
4075                         // after it.
4076                         i++;
4077                         if (i<N) {
4078                             aInfo = resolves.get(i).activityInfo;
4079                         }
4080                         if (debug) {
4081                             Slog.v(TAG, "Next matching activity: found current " + r.packageName
4082                                     + "/" + r.info.name);
4083                             Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
4084                                     + "/" + aInfo.name);
4085                         }
4086                         break;
4087                     }
4088                 }
4089             } catch (RemoteException e) {
4090             }
4091
4092             if (aInfo == null) {
4093                 // Nobody who is next!
4094                 ActivityOptions.abort(options);
4095                 if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4096                 return false;
4097             }
4098
4099             intent.setComponent(new ComponentName(
4100                     aInfo.applicationInfo.packageName, aInfo.name));
4101             intent.setFlags(intent.getFlags()&~(
4102                     Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4103                     Intent.FLAG_ACTIVITY_CLEAR_TOP|
4104                     Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4105                     Intent.FLAG_ACTIVITY_NEW_TASK));
4106
4107             // Okay now we need to start the new activity, replacing the
4108             // currently running activity.  This is a little tricky because
4109             // we want to start the new one as if the current one is finished,
4110             // but not finish the current one first so that there is no flicker.
4111             // And thus...
4112             final boolean wasFinishing = r.finishing;
4113             r.finishing = true;
4114
4115             // Propagate reply information over to the new activity.
4116             final ActivityRecord resultTo = r.resultTo;
4117             final String resultWho = r.resultWho;
4118             final int requestCode = r.requestCode;
4119             r.resultTo = null;
4120             if (resultTo != null) {
4121                 resultTo.removeResultsLocked(r, resultWho, requestCode);
4122             }
4123
4124             final long origId = Binder.clearCallingIdentity();
4125             int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
4126                     r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
4127                     resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage,
4128                     -1, r.launchedFromUid, 0, options, false, false, null, null, null);
4129             Binder.restoreCallingIdentity(origId);
4130
4131             r.finishing = wasFinishing;
4132             if (res != ActivityManager.START_SUCCESS) {
4133                 return false;
4134             }
4135             return true;
4136         }
4137     }
4138
4139     @Override
4140     public final int startActivityFromRecents(int taskId, Bundle options) {
4141         if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4142             String msg = "Permission Denial: startActivityFromRecents called without " +
4143                     START_TASKS_FROM_RECENTS;
4144             Slog.w(TAG, msg);
4145             throw new SecurityException(msg);
4146         }
4147         return startActivityFromRecentsInner(taskId, options);
4148     }
4149
4150     final int startActivityFromRecentsInner(int taskId, Bundle options) {
4151         final TaskRecord task;
4152         final int callingUid;
4153         final String callingPackage;
4154         final Intent intent;
4155         final int userId;
4156         synchronized (this) {
4157             task = mStackSupervisor.anyTaskForIdLocked(taskId);
4158             if (task == null) {
4159                 throw new IllegalArgumentException("Task " + taskId + " not found.");
4160             }
4161             if (task.getRootActivity() != null) {
4162                 moveTaskToFrontLocked(task.taskId, 0, null);
4163                 return ActivityManager.START_TASK_TO_FRONT;
4164             }
4165             callingUid = task.mCallingUid;
4166             callingPackage = task.mCallingPackage;
4167             intent = task.intent;
4168             intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
4169             userId = task.userId;
4170         }
4171         return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
4172                 options, userId, null, task);
4173     }
4174
4175     final int startActivityInPackage(int uid, String callingPackage,
4176             Intent intent, String resolvedType, IBinder resultTo,
4177             String resultWho, int requestCode, int startFlags, Bundle options, int userId,
4178             IActivityContainer container, TaskRecord inTask) {
4179
4180         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
4181                 false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4182
4183         // TODO: Switch to user app stacks here.
4184         int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent,
4185                 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4186                 null, null, null, options, false, userId, container, inTask);
4187         return ret;
4188     }
4189
4190     @Override
4191     public final int startActivities(IApplicationThread caller, String callingPackage,
4192             Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
4193             int userId) {
4194         enforceNotIsolatedCaller("startActivities");
4195         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
4196                 false, ALLOW_FULL_ONLY, "startActivity", null);
4197         // TODO: Switch to user app stacks here.
4198         int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
4199                 resolvedTypes, resultTo, options, userId);
4200         return ret;
4201     }
4202
4203     final int startActivitiesInPackage(int uid, String callingPackage,
4204             Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4205             Bundle options, int userId) {
4206
4207         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
4208                 false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4209         // TODO: Switch to user app stacks here.
4210         int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4211                 resultTo, options, userId);
4212         return ret;
4213     }
4214
4215     @Override
4216     public void reportActivityFullyDrawn(IBinder token) {
4217         synchronized (this) {
4218             ActivityRecord r = ActivityRecord.isInStackLocked(token);
4219             if (r == null) {
4220                 return;
4221             }
4222             r.reportFullyDrawnLocked();
4223         }
4224     }
4225
4226     @Override
4227     public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4228         synchronized (this) {
4229             ActivityRecord r = ActivityRecord.isInStackLocked(token);
4230             if (r == null) {
4231                 return;
4232             }
4233             if (r.task != null && r.task.mResizeable) {
4234                 // Fixed screen orientation isn't supported with resizeable activities.
4235                 return;
4236             }
4237             final long origId = Binder.clearCallingIdentity();
4238             mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4239             Configuration config = mWindowManager.updateOrientationFromAppTokens(
4240                     mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4241             if (config != null) {
4242                 r.frozenBeforeDestroy = true;
4243                 if (!updateConfigurationLocked(config, r, false, false)) {
4244                     mStackSupervisor.resumeTopActivitiesLocked();
4245                 }
4246             }
4247             Binder.restoreCallingIdentity(origId);
4248         }
4249     }
4250
4251     @Override
4252     public int getRequestedOrientation(IBinder token) {
4253         synchronized (this) {
4254             ActivityRecord r = ActivityRecord.isInStackLocked(token);
4255             if (r == null) {
4256                 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4257             }
4258             return mWindowManager.getAppOrientation(r.appToken);
4259         }
4260     }
4261
4262     /**
4263      * This is the internal entry point for handling Activity.finish().
4264      *
4265      * @param token The Binder token referencing the Activity we want to finish.
4266      * @param resultCode Result code, if any, from this Activity.
4267      * @param resultData Result data (Intent), if any, from this Activity.
4268      * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
4269      *            the root Activity in the task.
4270      *
4271      * @return Returns true if the activity successfully finished, or false if it is still running.
4272      */
4273     @Override
4274     public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4275             boolean finishTask) {
4276         // Refuse possible leaked file descriptors
4277         if (resultData != null && resultData.hasFileDescriptors() == true) {
4278             throw new IllegalArgumentException("File descriptors passed in Intent");
4279         }
4280
4281         synchronized(this) {
4282             ActivityRecord r = ActivityRecord.isInStackLocked(token);
4283             if (r == null) {
4284                 return true;
4285             }
4286             // Keep track of the root activity of the task before we finish it
4287             TaskRecord tr = r.task;
4288             ActivityRecord rootR = tr.getRootActivity();
4289             if (rootR == null) {
4290                 Slog.w(TAG, "Finishing task with all activities already finished");
4291             }
4292             // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
4293             // finish.
4294             if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
4295                     mStackSupervisor.isLastLockedTask(tr)) {
4296                 Slog.i(TAG, "Not finishing task in lock task mode");
4297                 mStackSupervisor.showLockTaskToast();
4298                 return false;
4299             }
4300             if (mController != null) {
4301                 // Find the first activity that is not finishing.
4302                 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4303                 if (next != null) {
4304                     // ask watcher if this is allowed
4305                     boolean resumeOK = true;
4306                     try {
4307                         resumeOK = mController.activityResuming(next.packageName);
4308                     } catch (RemoteException e) {
4309                         mController = null;
4310                         Watchdog.getInstance().setActivityController(null);
4311                     }
4312
4313                     if (!resumeOK) {
4314                         Slog.i(TAG, "Not finishing activity because controller resumed");
4315                         return false;
4316                     }
4317                 }
4318             }
4319             final long origId = Binder.clearCallingIdentity();
4320             try {
4321                 boolean res;
4322                 if (finishTask && r == rootR) {
4323                     // If requested, remove the task that is associated to this activity only if it
4324                     // was the root activity in the task. The result code and data is ignored
4325                     // because we don't support returning them across task boundaries.
4326                     res = removeTaskByIdLocked(tr.taskId, false);
4327                     if (!res) {
4328                         Slog.i(TAG, "Removing task failed to finish activity");
4329                     }
4330                 } else {
4331                     res = tr.stack.requestFinishActivityLocked(token, resultCode,
4332                             resultData, "app-request", true);
4333                     if (!res) {
4334                         Slog.i(TAG, "Failed to finish by app-request");
4335                     }
4336                 }
4337                 return res;
4338             } finally {
4339                 Binder.restoreCallingIdentity(origId);
4340             }
4341         }
4342     }
4343
4344     @Override
4345     public final void finishHeavyWeightApp() {
4346         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4347                 != PackageManager.PERMISSION_GRANTED) {
4348             String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4349                     + Binder.getCallingPid()
4350                     + ", uid=" + Binder.getCallingUid()
4351                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4352             Slog.w(TAG, msg);
4353             throw new SecurityException(msg);
4354         }
4355
4356         synchronized(this) {
4357             if (mHeavyWeightProcess == null) {
4358                 return;
4359             }
4360
4361             ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
4362             for (int i = 0; i < activities.size(); i++) {
4363                 ActivityRecord r = activities.get(i);
4364                 if (!r.finishing && r.isInStackLocked()) {
4365                     r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4366                             null, "finish-heavy", true);
4367                 }
4368             }
4369
4370             mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4371                     mHeavyWeightProcess.userId, 0));
4372             mHeavyWeightProcess = null;
4373         }
4374     }
4375
4376     @Override
4377     public void crashApplication(int uid, int initialPid, String packageName,
4378             String message) {
4379         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4380                 != PackageManager.PERMISSION_GRANTED) {
4381             String msg = "Permission Denial: crashApplication() from pid="
4382                     + Binder.getCallingPid()
4383                     + ", uid=" + Binder.getCallingUid()
4384                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4385             Slog.w(TAG, msg);
4386             throw new SecurityException(msg);
4387         }
4388
4389         synchronized(this) {
4390             ProcessRecord proc = null;
4391
4392             // Figure out which process to kill.  We don't trust that initialPid
4393             // still has any relation to current pids, so must scan through the
4394             // list.
4395             synchronized (mPidsSelfLocked) {
4396                 for (int i=0; i<mPidsSelfLocked.size(); i++) {
4397                     ProcessRecord p = mPidsSelfLocked.valueAt(i);
4398                     if (p.uid != uid) {
4399                         continue;
4400                     }
4401                     if (p.pid == initialPid) {
4402                         proc = p;
4403                         break;
4404                     }
4405                     if (p.pkgList.containsKey(packageName)) {
4406                         proc = p;
4407                     }
4408                 }
4409             }
4410
4411             if (proc == null) {
4412                 Slog.w(TAG, "crashApplication: nothing for uid=" + uid
4413                         + " initialPid=" + initialPid
4414                         + " packageName=" + packageName);
4415                 return;
4416             }
4417
4418             if (proc.thread != null) {
4419                 if (proc.pid == Process.myPid()) {
4420                     Log.w(TAG, "crashApplication: trying to crash self!");
4421                     return;
4422                 }
4423                 long ident = Binder.clearCallingIdentity();
4424                 try {
4425                     proc.thread.scheduleCrash(message);
4426                 } catch (RemoteException e) {
4427                 }
4428                 Binder.restoreCallingIdentity(ident);
4429             }
4430         }
4431     }
4432
4433     @Override
4434     public final void finishSubActivity(IBinder token, String resultWho,
4435             int requestCode) {
4436         synchronized(this) {
4437             final long origId = Binder.clearCallingIdentity();
4438             ActivityRecord r = ActivityRecord.isInStackLocked(token);
4439             if (r != null) {
4440                 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4441             }
4442             Binder.restoreCallingIdentity(origId);
4443         }
4444     }
4445
4446     @Override
4447     public boolean finishActivityAffinity(IBinder token) {
4448         synchronized(this) {
4449             final long origId = Binder.clearCallingIdentity();
4450             try {
4451                 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4452                 if (r == null) {
4453                     return false;
4454                 }
4455
4456                 // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
4457                 // can finish.
4458                 final TaskRecord task = r.task;
4459                 if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
4460                         mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
4461                     mStackSupervisor.showLockTaskToast();
4462                     return false;
4463                 }
4464                 return task.stack.finishActivityAffinityLocked(r);
4465             } finally {
4466                 Binder.restoreCallingIdentity(origId);
4467             }
4468         }
4469     }
4470
4471     @Override
4472     public void finishVoiceTask(IVoiceInteractionSession session) {
4473         synchronized(this) {
4474             final long origId = Binder.clearCallingIdentity();
4475             try {
4476                 mStackSupervisor.finishVoiceTask(session);
4477             } finally {
4478                 Binder.restoreCallingIdentity(origId);
4479             }
4480         }
4481
4482     }
4483
4484     @Override
4485     public boolean releaseActivityInstance(IBinder token) {
4486         synchronized(this) {
4487             final long origId = Binder.clearCallingIdentity();
4488             try {
4489                 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4490                 if (r == null) {
4491                     return false;
4492                 }
4493                 return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4494             } finally {
4495                 Binder.restoreCallingIdentity(origId);
4496             }
4497         }
4498     }
4499
4500     @Override
4501     public void releaseSomeActivities(IApplicationThread appInt) {
4502         synchronized(this) {
4503             final long origId = Binder.clearCallingIdentity();
4504             try {
4505                 ProcessRecord app = getRecordForAppLocked(appInt);
4506                 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4507             } finally {
4508                 Binder.restoreCallingIdentity(origId);
4509             }
4510         }
4511     }
4512
4513     @Override
4514     public boolean willActivityBeVisible(IBinder token) {
4515         synchronized(this) {
4516             ActivityStack stack = ActivityRecord.getStackLocked(token);
4517             if (stack != null) {
4518                 return stack.willActivityBeVisibleLocked(token);
4519             }
4520             return false;
4521         }
4522     }
4523
4524     @Override
4525     public void overridePendingTransition(IBinder token, String packageName,
4526             int enterAnim, int exitAnim) {
4527         synchronized(this) {
4528             ActivityRecord self = ActivityRecord.isInStackLocked(token);
4529             if (self == null) {
4530                 return;
4531             }
4532
4533             final long origId = Binder.clearCallingIdentity();
4534
4535             if (self.state == ActivityState.RESUMED
4536                     || self.state == ActivityState.PAUSING) {
4537                 mWindowManager.overridePendingAppTransition(packageName,
4538                         enterAnim, exitAnim, null);
4539             }
4540
4541             Binder.restoreCallingIdentity(origId);
4542         }
4543     }
4544
4545     /**
4546      * Main function for removing an existing process from the activity manager
4547      * as a result of that process going away.  Clears out all connections
4548      * to the process.
4549      */
4550     private final void handleAppDiedLocked(ProcessRecord app,
4551             boolean restarting, boolean allowRestart) {
4552         int pid = app.pid;
4553         boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4554         if (!kept && !restarting) {
4555             removeLruProcessLocked(app);
4556             if (pid > 0) {
4557                 ProcessList.remove(pid);
4558             }
4559         }
4560
4561         if (mProfileProc == app) {
4562             clearProfilerLocked();
4563         }
4564
4565         // Remove this application's activities from active lists.
4566         boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4567
4568         app.activities.clear();
4569
4570         if (app.instrumentationClass != null) {
4571             Slog.w(TAG, "Crash of app " + app.processName
4572                   + " running instrumentation " + app.instrumentationClass);
4573             Bundle info = new Bundle();
4574             info.putString("shortMsg", "Process crashed.");
4575             finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4576         }
4577
4578         if (!restarting && hasVisibleActivities && !mStackSupervisor.resumeTopActivitiesLocked()) {
4579             // If there was nothing to resume, and we are not already
4580             // restarting this process, but there is a visible activity that
4581             // is hosted by the process...  then make sure all visible
4582             // activities are running, taking care of restarting this
4583             // process.
4584             mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
4585         }
4586     }
4587
4588     private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4589         IBinder threadBinder = thread.asBinder();
4590         // Find the application record.
4591         for (int i=mLruProcesses.size()-1; i>=0; i--) {
4592             ProcessRecord rec = mLruProcesses.get(i);
4593             if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4594                 return i;
4595             }
4596         }
4597         return -1;
4598     }
4599
4600     final ProcessRecord getRecordForAppLocked(
4601             IApplicationThread thread) {
4602         if (thread == null) {
4603             return null;
4604         }
4605
4606         int appIndex = getLRURecordIndexForAppLocked(thread);
4607         return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4608     }
4609
4610     final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4611         // If there are no longer any background processes running,
4612         // and the app that died was not running instrumentation,
4613         // then tell everyone we are now low on memory.
4614         boolean haveBg = false;
4615         for (int i=mLruProcesses.size()-1; i>=0; i--) {
4616             ProcessRecord rec = mLruProcesses.get(i);
4617             if (rec.thread != null
4618                     && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4619                 haveBg = true;
4620                 break;
4621             }
4622         }
4623
4624         if (!haveBg) {
4625             boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4626             if (doReport) {
4627                 long now = SystemClock.uptimeMillis();
4628                 if (now < (mLastMemUsageReportTime+5*60*1000)) {
4629                     doReport = false;
4630                 } else {
4631                     mLastMemUsageReportTime = now;
4632                 }
4633             }
4634             final ArrayList<ProcessMemInfo> memInfos
4635                     = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4636             EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4637             long now = SystemClock.uptimeMillis();
4638             for (int i=mLruProcesses.size()-1; i>=0; i--) {
4639                 ProcessRecord rec = mLruProcesses.get(i);
4640                 if (rec == dyingProc || rec.thread == null) {
4641                     continue;
4642                 }
4643                 if (doReport) {
4644                     memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4645                             rec.setProcState, rec.adjType, rec.makeAdjReason()));
4646                 }
4647                 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4648                     // The low memory report is overriding any current
4649                     // state for a GC request.  Make sure to do
4650                     // heavy/important/visible/foreground processes first.
4651                     if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4652                         rec.lastRequestedGc = 0;
4653                     } else {
4654                         rec.lastRequestedGc = rec.lastLowMemory;
4655                     }
4656                     rec.reportLowMemory = true;
4657                     rec.lastLowMemory = now;
4658                     mProcessesToGc.remove(rec);
4659                     addProcessToGcListLocked(rec);
4660                 }
4661             }
4662             if (doReport) {
4663                 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4664                 mHandler.sendMessage(msg);
4665             }
4666             scheduleAppGcsLocked();
4667         }
4668     }
4669
4670     final void appDiedLocked(ProcessRecord app) {
4671        appDiedLocked(app, app.pid, app.thread, false);
4672     }
4673
4674     final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
4675             boolean fromBinderDied) {
4676         // First check if this ProcessRecord is actually active for the pid.
4677         synchronized (mPidsSelfLocked) {
4678             ProcessRecord curProc = mPidsSelfLocked.get(pid);
4679             if (curProc != app) {
4680                 Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
4681                 return;
4682             }
4683         }
4684
4685         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4686         synchronized (stats) {
4687             stats.noteProcessDiedLocked(app.info.uid, pid);
4688         }
4689
4690         if (!app.killed) {
4691             if (!fromBinderDied) {
4692                 Process.killProcessQuiet(pid);
4693             }
4694             killProcessGroup(app.info.uid, pid);
4695             app.killed = true;
4696         }
4697
4698         // Clean up already done if the process has been re-started.
4699         if (app.pid == pid && app.thread != null &&
4700                 app.thread.asBinder() == thread.asBinder()) {
4701             boolean doLowMem = app.instrumentationClass == null;
4702             boolean doOomAdj = doLowMem;
4703             if (!app.killedByAm) {
4704                 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4705                         + ") has died");
4706                 mAllowLowerMemLevel = true;
4707             } else {
4708                 // Note that we always want to do oom adj to update our state with the
4709                 // new number of procs.
4710                 mAllowLowerMemLevel = false;
4711                 doLowMem = false;
4712             }
4713             EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4714             if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
4715                 "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
4716             handleAppDiedLocked(app, false, true);
4717
4718             if (doOomAdj) {
4719                 updateOomAdjLocked();
4720             }
4721             if (doLowMem) {
4722                 doLowMemReportIfNeededLocked(app);
4723             }
4724         } else if (app.pid != pid) {
4725             // A new process has already been started.
4726             Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4727                     + ") has died and restarted (pid " + app.pid + ").");
4728             EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4729         } else if (DEBUG_PROCESSES) {
4730             Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
4731                     + thread.asBinder());
4732         }
4733     }
4734
4735     /**
4736      * If a stack trace dump file is configured, dump process stack traces.
4737      * @param clearTraces causes the dump file to be erased prior to the new
4738      *    traces being written, if true; when false, the new traces will be
4739      *    appended to any existing file content.
4740      * @param firstPids of dalvik VM processes to dump stack traces for first
4741      * @param lastPids of dalvik VM processes to dump stack traces for last
4742      * @param nativeProcs optional list of native process names to dump stack crawls
4743      * @return file containing stack traces, or null if no dump file is configured
4744      */
4745     public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4746             ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4747         String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4748         if (tracesPath == null || tracesPath.length() == 0) {
4749             return null;
4750         }
4751
4752         File tracesFile = new File(tracesPath);
4753         try {
4754             File tracesDir = tracesFile.getParentFile();
4755             if (!tracesDir.exists()) {
4756                 tracesDir.mkdirs();
4757                 if (!SELinux.restorecon(tracesDir)) {
4758                     return null;
4759                 }
4760             }
4761             FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4762
4763             if (clearTraces && tracesFile.exists()) tracesFile.delete();
4764             tracesFile.createNewFile();
4765             FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4766         } catch (IOException e) {
4767             Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4768             return null;
4769         }
4770
4771         dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4772         return tracesFile;
4773     }
4774
4775     private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4776             ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4777         // Use a FileObserver to detect when traces finish writing.
4778         // The order of traces is considered important to maintain for legibility.
4779         FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4780             @Override
4781             public synchronized void onEvent(int event, String path) { notify(); }
4782         };
4783
4784         try {
4785             observer.startWatching();
4786
4787             // First collect all of the stacks of the most important pids.
4788             if (firstPids != null) {
4789                 try {
4790                     int num = firstPids.size();
4791                     for (int i = 0; i < num; i++) {
4792                         synchronized (observer) {
4793                             Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4794                             observer.wait(200);  // Wait for write-close, give up after 200msec
4795                         }
4796                     }
4797                 } catch (InterruptedException e) {
4798                     Slog.wtf(TAG, e);
4799                 }
4800             }
4801
4802             // Next collect the stacks of the native pids
4803             if (nativeProcs != null) {
4804                 int[] pids = Process.getPidsForCommands(nativeProcs);
4805                 if (pids != null) {
4806                     for (int pid : pids) {
4807                         Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4808                     }
4809                 }
4810             }
4811
4812             // Lastly, measure CPU usage.
4813             if (processCpuTracker != null) {
4814                 processCpuTracker.init();
4815                 System.gc();
4816                 processCpuTracker.update();
4817                 try {
4818                     synchronized (processCpuTracker) {
4819                         processCpuTracker.wait(500); // measure over 1/2 second.
4820                     }
4821                 } catch (InterruptedException e) {
4822                 }
4823                 processCpuTracker.update();
4824
4825                 // We'll take the stack crawls of just the top apps using CPU.
4826                 final int N = processCpuTracker.countWorkingStats();
4827                 int numProcs = 0;
4828                 for (int i=0; i<N && numProcs<5; i++) {
4829                     ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4830                     if (lastPids.indexOfKey(stats.pid) >= 0) {
4831                         numProcs++;
4832                         try {
4833                             synchronized (observer) {
4834                                 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4835                                 observer.wait(200);  // Wait for write-close, give up after 200msec
4836                             }
4837                         } catch (InterruptedException e) {
4838                             Slog.wtf(TAG, e);
4839                         }
4840
4841                     }
4842                 }
4843             }
4844         } finally {
4845             observer.stopWatching();
4846         }
4847     }
4848
4849     final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4850         if (true || IS_USER_BUILD) {
4851             return;
4852         }
4853         String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4854         if (tracesPath == null || tracesPath.length() == 0) {
4855             return;
4856         }
4857
4858         StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4859         StrictMode.allowThreadDiskWrites();
4860         try {
4861             final File tracesFile = new File(tracesPath);
4862             final File tracesDir = tracesFile.getParentFile();
4863             final File tracesTmp = new File(tracesDir, "__tmp__");
4864             try {
4865                 if (!tracesDir.exists()) {
4866                     tracesDir.mkdirs();
4867                     if (!SELinux.restorecon(tracesDir.getPath())) {
4868                         return;
4869                     }
4870                 }
4871                 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4872
4873                 if (tracesFile.exists()) {
4874                     tracesTmp.delete();
4875                     tracesFile.renameTo(tracesTmp);
4876                 }
4877                 StringBuilder sb = new StringBuilder();
4878                 Time tobj = new Time();
4879                 tobj.set(System.currentTimeMillis());
4880                 sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4881                 sb.append(": ");
4882                 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4883                 sb.append(" since ");
4884                 sb.append(msg);
4885                 FileOutputStream fos = new FileOutputStream(tracesFile);
4886                 fos.write(sb.toString().getBytes());
4887                 if (app == null) {
4888                     fos.write("\n*** No application process!".getBytes());
4889                 }
4890                 fos.close();
4891                 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4892             } catch (IOException e) {
4893                 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4894                 return;
4895             }
4896
4897             if (app != null) {
4898                 ArrayList<Integer> firstPids = new ArrayList<Integer>();
4899                 firstPids.add(app.pid);
4900                 dumpStackTraces(tracesPath, firstPids, null, null, null);
4901             }
4902
4903             File lastTracesFile = null;
4904             File curTracesFile = null;
4905             for (int i=9; i>=0; i--) {
4906                 String name = String.format(Locale.US, "slow%02d.txt", i);
4907                 curTracesFile = new File(tracesDir, name);
4908                 if (curTracesFile.exists()) {
4909                     if (lastTracesFile != null) {
4910                         curTracesFile.renameTo(lastTracesFile);
4911                     } else {
4912                         curTracesFile.delete();
4913                     }
4914                 }
4915                 lastTracesFile = curTracesFile;
4916             }
4917             tracesFile.renameTo(curTracesFile);
4918             if (tracesTmp.exists()) {
4919                 tracesTmp.renameTo(tracesFile);
4920             }
4921         } finally {
4922             StrictMode.setThreadPolicy(oldPolicy);
4923         }
4924     }
4925
4926     final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4927             ActivityRecord parent, boolean aboveSystem, final String annotation) {
4928         ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4929         SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4930
4931         if (mController != null) {
4932             try {
4933                 // 0 == continue, -1 = kill process immediately
4934                 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4935                 if (res < 0 && app.pid != MY_PID) {
4936                     app.kill("anr", true);
4937                 }
4938             } catch (RemoteException e) {
4939                 mController = null;
4940                 Watchdog.getInstance().setActivityController(null);
4941             }
4942         }
4943
4944         long anrTime = SystemClock.uptimeMillis();
4945         if (MONITOR_CPU_USAGE) {
4946             updateCpuStatsNow();
4947         }
4948
4949         synchronized (this) {
4950             // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4951             if (mShuttingDown) {
4952                 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4953                 return;
4954             } else if (app.notResponding) {
4955                 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4956                 return;
4957             } else if (app.crashing) {
4958                 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4959                 return;
4960             }
4961
4962             // In case we come through here for the same app before completing
4963             // this one, mark as anring now so we will bail out.
4964             app.notResponding = true;
4965
4966             // Log the ANR to the event log.
4967             EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4968                     app.processName, app.info.flags, annotation);
4969
4970             // Dump thread traces as quickly as we can, starting with "interesting" processes.
4971             firstPids.add(app.pid);
4972
4973             int parentPid = app.pid;
4974             if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4975             if (parentPid != app.pid) firstPids.add(parentPid);
4976
4977             if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4978
4979             for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4980                 ProcessRecord r = mLruProcesses.get(i);
4981                 if (r != null && r.thread != null) {
4982                     int pid = r.pid;
4983                     if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4984                         if (r.persistent) {
4985                             firstPids.add(pid);
4986                         } else {
4987                             lastPids.put(pid, Boolean.TRUE);
4988                         }
4989                     }
4990                 }
4991             }
4992         }
4993
4994         // Log the ANR to the main log.
4995         StringBuilder info = new StringBuilder();
4996         info.setLength(0);
4997         info.append("ANR in ").append(app.processName);
4998         if (activity != null && activity.shortComponentName != null) {
4999             info.append(" (").append(activity.shortComponentName).append(")");
5000         }
5001         info.append("\n");
5002         info.append("PID: ").append(app.pid).append("\n");
5003         if (annotation != null) {
5004             info.append("Reason: ").append(annotation).append("\n");
5005         }
5006         if (parent != null && parent != activity) {
5007             info.append("Parent: ").append(parent.shortComponentName).append("\n");
5008         }
5009
5010         final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
5011
5012         File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
5013                 NATIVE_STACKS_OF_INTEREST);
5014
5015         String cpuInfo = null;
5016         if (MONITOR_CPU_USAGE) {
5017             updateCpuStatsNow();
5018             synchronized (mProcessCpuTracker) {
5019                 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
5020             }
5021             info.append(processCpuTracker.printCurrentLoad());
5022             info.append(cpuInfo);
5023         }
5024
5025         info.append(processCpuTracker.printCurrentState(anrTime));
5026
5027         Slog.e(TAG, info.toString());
5028         if (tracesFile == null) {
5029             // There is no trace file, so dump (only) the alleged culprit's threads to the log
5030             Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
5031         }
5032
5033         addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
5034                 cpuInfo, tracesFile, null);
5035
5036         if (mController != null) {
5037             try {
5038                 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
5039                 int res = mController.appNotResponding(app.processName, app.pid, info.toString());
5040                 if (res != 0) {
5041                     if (res < 0 && app.pid != MY_PID) {
5042                         app.kill("anr", true);
5043                     } else {
5044                         synchronized (this) {
5045                             mServices.scheduleServiceTimeoutLocked(app);
5046                         }
5047                     }
5048                     return;
5049                 }
5050             } catch (RemoteException e) {
5051                 mController = null;
5052                 Watchdog.getInstance().setActivityController(null);
5053             }
5054         }
5055
5056         // Unless configured otherwise, swallow ANRs in background processes & kill the process.
5057         boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
5058                 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
5059
5060         synchronized (this) {
5061             mBatteryStatsService.noteProcessAnr(app.processName, app.uid);
5062
5063             if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
5064                 app.kill("bg anr", true);
5065                 return;
5066             }
5067
5068             // Set the app's notResponding state, and look up the errorReportReceiver
5069             makeAppNotRespondingLocked(app,
5070                     activity != null ? activity.shortComponentName : null,
5071                     annotation != null ? "ANR " + annotation : "ANR",
5072                     info.toString());
5073
5074             // Bring up the infamous App Not Responding dialog
5075             Message msg = Message.obtain();
5076             HashMap<String, Object> map = new HashMap<String, Object>();
5077             msg.what = SHOW_NOT_RESPONDING_MSG;
5078             msg.obj = map;
5079             msg.arg1 = aboveSystem ? 1 : 0;
5080             map.put("app", app);
5081             if (activity != null) {
5082                 map.put("activity", activity);
5083             }
5084
5085             mUiHandler.sendMessage(msg);
5086         }
5087     }
5088
5089     final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5090         if (!mLaunchWarningShown) {
5091             mLaunchWarningShown = true;
5092             mUiHandler.post(new Runnable() {
5093                 @Override
5094                 public void run() {
5095                     synchronized (ActivityManagerService.this) {
5096                         final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5097                         d.show();
5098                         mUiHandler.postDelayed(new Runnable() {
5099                             @Override
5100                             public void run() {
5101                                 synchronized (ActivityManagerService.this) {
5102                                     d.dismiss();
5103                                     mLaunchWarningShown = false;
5104                                 }
5105                             }
5106                         }, 4000);
5107                     }
5108                 }
5109             });
5110         }
5111     }
5112
5113     @Override
5114     public boolean clearApplicationUserData(final String packageName,
5115             final IPackageDataObserver observer, int userId) {
5116         enforceNotIsolatedCaller("clearApplicationUserData");
5117         if (packageName != null && packageName.equals(mDeviceOwnerName)) {
5118             throw new SecurityException("Clearing DeviceOwner data is forbidden.");
5119         }
5120         int uid = Binder.getCallingUid();
5121         int pid = Binder.getCallingPid();
5122         userId = handleIncomingUser(pid, uid,
5123                 userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5124         long callingId = Binder.clearCallingIdentity();
5125         try {
5126             IPackageManager pm = AppGlobals.getPackageManager();
5127             int pkgUid = -1;
5128             synchronized(this) {
5129                 try {
5130                     pkgUid = pm.getPackageUid(packageName, userId);
5131                 } catch (RemoteException e) {
5132                 }
5133                 if (pkgUid == -1) {
5134                     Slog.w(TAG, "Invalid packageName: " + packageName);
5135                     if (observer != null) {
5136                         try {
5137                             observer.onRemoveCompleted(packageName, false);
5138                         } catch (RemoteException e) {
5139                             Slog.i(TAG, "Observer no longer exists.");
5140                         }
5141                     }
5142                     return false;
5143                 }
5144                 if (uid == pkgUid || checkComponentPermission(
5145                         android.Manifest.permission.CLEAR_APP_USER_DATA,
5146                         pid, uid, -1, true)
5147                         == PackageManager.PERMISSION_GRANTED) {
5148                     forceStopPackageLocked(packageName, pkgUid, "clear data");
5149                 } else {
5150                     throw new SecurityException("PID " + pid + " does not have permission "
5151                             + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5152                                     + " of package " + packageName);
5153                 }
5154
5155                 // Remove all tasks match the cleared application package and user
5156                 for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5157                     final TaskRecord tr = mRecentTasks.get(i);
5158                     final String taskPackageName =
5159                             tr.getBaseIntent().getComponent().getPackageName();
5160                     if (tr.userId != userId) continue;
5161                     if (!taskPackageName.equals(packageName)) continue;
5162                     removeTaskByIdLocked(tr.taskId, false);
5163                 }
5164             }
5165
5166             try {
5167                 // Clear application user data
5168                 pm.clearApplicationUserData(packageName, observer, userId);
5169
5170                 synchronized(this) {
5171                     // Remove all permissions granted from/to this package
5172                     removeUriPermissionsForPackageLocked(packageName, userId, true);
5173                 }
5174
5175                 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5176                         Uri.fromParts("package", packageName, null));
5177                 intent.putExtra(Intent.EXTRA_UID, pkgUid);
5178                 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5179                         null, null, 0, null, null, null, null, false, false, userId);
5180             } catch (RemoteException e) {
5181             }
5182         } finally {
5183             Binder.restoreCallingIdentity(callingId);
5184         }
5185         return true;
5186     }
5187
5188     @Override
5189     public void killBackgroundProcesses(final String packageName, int userId) {
5190         if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5191                 != PackageManager.PERMISSION_GRANTED &&
5192                 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5193                         != PackageManager.PERMISSION_GRANTED) {
5194             String msg = "Permission Denial: killBackgroundProcesses() from pid="
5195                     + Binder.getCallingPid()
5196                     + ", uid=" + Binder.getCallingUid()
5197                     + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5198             Slog.w(TAG, msg);
5199             throw new SecurityException(msg);
5200         }
5201
5202         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5203                 userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5204         long callingId = Binder.clearCallingIdentity();
5205         try {
5206             IPackageManager pm = AppGlobals.getPackageManager();
5207             synchronized(this) {
5208                 int appId = -1;
5209                 try {
5210                     appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
5211                 } catch (RemoteException e) {
5212                 }
5213                 if (appId == -1) {
5214                     Slog.w(TAG, "Invalid packageName: " + packageName);
5215                     return;
5216                 }
5217                 killPackageProcessesLocked(packageName, appId, userId,
5218                         ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5219             }
5220         } finally {
5221             Binder.restoreCallingIdentity(callingId);
5222         }
5223     }
5224
5225     @Override
5226     public void killAllBackgroundProcesses() {
5227         if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5228                 != PackageManager.PERMISSION_GRANTED) {
5229             String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5230                     + Binder.getCallingPid()
5231                     + ", uid=" + Binder.getCallingUid()
5232                     + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5233             Slog.w(TAG, msg);
5234             throw new SecurityException(msg);
5235         }
5236
5237         long callingId = Binder.clearCallingIdentity();
5238         try {
5239             synchronized(this) {
5240                 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5241                 final int NP = mProcessNames.getMap().size();
5242                 for (int ip=0; ip<NP; ip++) {
5243                     SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5244                     final int NA = apps.size();
5245                     for (int ia=0; ia<NA; ia++) {
5246                         ProcessRecord app = apps.valueAt(ia);
5247                         if (app.persistent) {
5248                             // we don't kill persistent processes
5249                             continue;
5250                         }
5251                         if (app.removed) {
5252                             procs.add(app);
5253                         } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5254                             app.removed = true;
5255                             procs.add(app);
5256                         }
5257                     }
5258                 }
5259
5260                 int N = procs.size();
5261                 for (int i=0; i<N; i++) {
5262                     removeProcessLocked(procs.get(i), false, true, "kill all background");
5263                 }
5264                 mAllowLowerMemLevel = true;
5265                 updateOomAdjLocked();
5266                 doLowMemReportIfNeededLocked(null);
5267             }
5268         } finally {
5269             Binder.restoreCallingIdentity(callingId);
5270         }
5271     }
5272
5273     @Override
5274     public void forceStopPackage(final String packageName, int userId) {
5275         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5276                 != PackageManager.PERMISSION_GRANTED) {
5277             String msg = "Permission Denial: forceStopPackage() from pid="
5278                     + Binder.getCallingPid()
5279                     + ", uid=" + Binder.getCallingUid()
5280                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5281             Slog.w(TAG, msg);
5282             throw new SecurityException(msg);
5283         }
5284         final int callingPid = Binder.getCallingPid();
5285         userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
5286                 userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5287         long callingId = Binder.clearCallingIdentity();
5288         try {
5289             IPackageManager pm = AppGlobals.getPackageManager();
5290             synchronized(this) {
5291                 int[] users = userId == UserHandle.USER_ALL
5292                         ? getUsersLocked() : new int[] { userId };
5293                 for (int user : users) {
5294                     int pkgUid = -1;
5295                     try {
5296                         pkgUid = pm.getPackageUid(packageName, user);
5297                     } catch (RemoteException e) {
5298                     }
5299                     if (pkgUid == -1) {
5300                         Slog.w(TAG, "Invalid packageName: " + packageName);
5301                         continue;
5302                     }
5303                     try {
5304                         pm.setPackageStoppedState(packageName, true, user);
5305                     } catch (RemoteException e) {
5306                     } catch (IllegalArgumentException e) {
5307                         Slog.w(TAG, "Failed trying to unstop package "
5308                                 + packageName + ": " + e);
5309                     }
5310                     if (isUserRunningLocked(user, false)) {
5311                         forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5312                     }
5313                 }
5314             }
5315         } finally {
5316             Binder.restoreCallingIdentity(callingId);
5317         }
5318     }
5319
5320     @Override
5321     public void addPackageDependency(String packageName) {
5322         synchronized (this) {
5323             int callingPid = Binder.getCallingPid();
5324             if (callingPid == Process.myPid()) {
5325                 //  Yeah, um, no.
5326                 return;
5327             }
5328             ProcessRecord proc;
5329             synchronized (mPidsSelfLocked) {
5330                 proc = mPidsSelfLocked.get(Binder.getCallingPid());
5331             }
5332             if (proc != null) {
5333                 if (proc.pkgDeps == null) {
5334                     proc.pkgDeps = new ArraySet<String>(1);
5335                 }
5336                 proc.pkgDeps.add(packageName);
5337             }
5338         }
5339     }
5340
5341     /*
5342      * The pkg name and app id have to be specified.
5343      */
5344     @Override
5345     public void killApplicationWithAppId(String pkg, int appid, String reason) {
5346         if (pkg == null) {
5347             return;
5348         }
5349         // Make sure the uid is valid.
5350         if (appid < 0) {
5351             Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5352             return;
5353         }
5354         int callerUid = Binder.getCallingUid();
5355         // Only the system server can kill an application
5356         if (UserHandle.getAppId(callerUid) == Process.SYSTEM_UID) {
5357             // Post an aysnc message to kill the application
5358             Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5359             msg.arg1 = appid;
5360             msg.arg2 = 0;
5361             Bundle bundle = new Bundle();
5362             bundle.putString("pkg", pkg);
5363             bundle.putString("reason", reason);
5364             msg.obj = bundle;
5365             mHandler.sendMessage(msg);
5366         } else {
5367             throw new SecurityException(callerUid + " cannot kill pkg: " +
5368                     pkg);
5369         }
5370     }
5371
5372     @Override
5373     public void closeSystemDialogs(String reason) {
5374         enforceNotIsolatedCaller("closeSystemDialogs");
5375
5376         final int pid = Binder.getCallingPid();
5377         final int uid = Binder.getCallingUid();
5378         final long origId = Binder.clearCallingIdentity();
5379         try {
5380             synchronized (this) {
5381                 // Only allow this from foreground processes, so that background
5382                 // applications can't abuse it to prevent system UI from being shown.
5383                 if (uid >= Process.FIRST_APPLICATION_UID) {
5384                     ProcessRecord proc;
5385                     synchronized (mPidsSelfLocked) {
5386                         proc = mPidsSelfLocked.get(pid);
5387                     }
5388                     if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5389                         Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5390                                 + " from background process " + proc);
5391                         return;
5392                     }
5393                 }
5394                 closeSystemDialogsLocked(reason);
5395             }
5396         } finally {
5397             Binder.restoreCallingIdentity(origId);
5398         }
5399     }
5400
5401     void closeSystemDialogsLocked(String reason) {
5402         Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5403         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5404                 | Intent.FLAG_RECEIVER_FOREGROUND);
5405         if (reason != null) {
5406             intent.putExtra("reason", reason);
5407         }
5408         mWindowManager.closeSystemDialogs(reason);
5409
5410         mStackSupervisor.closeSystemDialogsLocked();
5411
5412         broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
5413                 AppOpsManager.OP_NONE, null, false, false,
5414                 -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
5415     }
5416
5417     @Override
5418     public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5419         enforceNotIsolatedCaller("getProcessMemoryInfo");
5420         Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5421         for (int i=pids.length-1; i>=0; i--) {
5422             ProcessRecord proc;
5423             int oomAdj;
5424             synchronized (this) {
5425                 synchronized (mPidsSelfLocked) {
5426                     proc = mPidsSelfLocked.get(pids[i]);
5427                     oomAdj = proc != null ? proc.setAdj : 0;
5428                 }
5429             }
5430             infos[i] = new Debug.MemoryInfo();
5431             Debug.getMemoryInfo(pids[i], infos[i]);
5432             if (proc != null) {
5433                 synchronized (this) {
5434                     if (proc.thread != null && proc.setAdj == oomAdj) {
5435                         // Record this for posterity if the process has been stable.
5436                         proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5437                                 infos[i].getTotalUss(), false, proc.pkgList);
5438                     }
5439                 }
5440             }
5441         }
5442         return infos;
5443     }
5444
5445     @Override
5446     public long[] getProcessPss(int[] pids) {
5447         enforceNotIsolatedCaller("getProcessPss");
5448         long[] pss = new long[pids.length];
5449         for (int i=pids.length-1; i>=0; i--) {
5450             ProcessRecord proc;
5451             int oomAdj;
5452             synchronized (this) {
5453                 synchronized (mPidsSelfLocked) {
5454                     proc = mPidsSelfLocked.get(pids[i]);
5455                     oomAdj = proc != null ? proc.setAdj : 0;
5456                 }
5457             }
5458             long[] tmpUss = new long[1];
5459             pss[i] = Debug.getPss(pids[i], tmpUss, null);
5460             if (proc != null) {
5461                 synchronized (this) {
5462                     if (proc.thread != null && proc.setAdj == oomAdj) {
5463                         // Record this for posterity if the process has been stable.
5464                         proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5465                     }
5466                 }
5467             }
5468         }
5469         return pss;
5470     }
5471
5472     @Override
5473     public void killApplicationProcess(String processName, int uid) {
5474         if (processName == null) {
5475             return;
5476         }
5477
5478         int callerUid = Binder.getCallingUid();
5479         // Only the system server can kill an application
5480         if (callerUid == Process.SYSTEM_UID) {
5481             synchronized (this) {
5482                 ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5483                 if (app != null && app.thread != null) {
5484                     try {
5485                         app.thread.scheduleSuicide();
5486                     } catch (RemoteException e) {
5487                         // If the other end already died, then our work here is done.
5488                     }
5489                 } else {
5490                     Slog.w(TAG, "Process/uid not found attempting kill of "
5491                             + processName + " / " + uid);
5492                 }
5493             }
5494         } else {
5495             throw new SecurityException(callerUid + " cannot kill app process: " +
5496                     processName);
5497         }
5498     }
5499
5500     private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5501         forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5502                 false, true, false, false, UserHandle.getUserId(uid), reason);
5503         Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5504                 Uri.fromParts("package", packageName, null));
5505         if (!mProcessesReady) {
5506             intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5507                     | Intent.FLAG_RECEIVER_FOREGROUND);
5508         }
5509         intent.putExtra(Intent.EXTRA_UID, uid);
5510         intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5511         broadcastIntentLocked(null, null, intent,
5512                 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5513                 null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5514     }
5515
5516     private void forceStopUserLocked(int userId, String reason) {
5517         forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
5518         Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
5519         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5520                 | Intent.FLAG_RECEIVER_FOREGROUND);
5521         intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5522         broadcastIntentLocked(null, null, intent,
5523                 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5524                 null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
5525     }
5526
5527     private final boolean killPackageProcessesLocked(String packageName, int appId,
5528             int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5529             boolean doit, boolean evenPersistent, String reason) {
5530         ArrayList<ProcessRecord> procs = new ArrayList<>();
5531
5532         // Remove all processes this package may have touched: all with the
5533         // same UID (except for the system or root user), and all whose name
5534         // matches the package name.
5535         final int NP = mProcessNames.getMap().size();
5536         for (int ip=0; ip<NP; ip++) {
5537             SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5538             final int NA = apps.size();
5539             for (int ia=0; ia<NA; ia++) {
5540                 ProcessRecord app = apps.valueAt(ia);
5541                 if (app.persistent && !evenPersistent) {
5542                     // we don't kill persistent processes
5543                     continue;
5544                 }
5545                 if (app.removed) {
5546                     if (doit) {
5547                         procs.add(app);
5548                     }
5549                     continue;
5550                 }
5551
5552                 // Skip process if it doesn't meet our oom adj requirement.
5553                 if (app.setAdj < minOomAdj) {
5554                     continue;
5555                 }
5556
5557                 // If no package is specified, we call all processes under the
5558                 // give user id.
5559                 if (packageName == null) {
5560                     if (userId != UserHandle.USER_ALL && app.userId != userId) {
5561                         continue;
5562                     }
5563                     if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5564                         continue;
5565                     }
5566                 // Package has been specified, we want to hit all processes
5567                 // that match it.  We need to qualify this by the processes
5568                 // that are running under the specified app and user ID.
5569                 } else {
5570                     final boolean isDep = app.pkgDeps != null
5571                             && app.pkgDeps.contains(packageName);
5572                     if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5573                         continue;
5574                     }
5575                     if (userId != UserHandle.USER_ALL && app.userId != userId) {
5576                         continue;
5577                     }
5578                     if (!app.pkgList.containsKey(packageName) && !isDep) {
5579                         continue;
5580                     }
5581                 }
5582
5583                 // Process has passed all conditions, kill it!
5584                 if (!doit) {
5585                     return true;
5586                 }
5587                 app.removed = true;
5588                 procs.add(app);
5589             }
5590         }
5591
5592         int N = procs.size();
5593         for (int i=0; i<N; i++) {
5594             removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5595         }
5596         updateOomAdjLocked();
5597         return N > 0;
5598     }
5599
5600     private void cleanupDisabledPackageComponentsLocked(
5601             String packageName, int userId, boolean killProcess, String[] changedClasses) {
5602
5603         Set<String> disabledClasses = null;
5604         boolean packageDisabled = false;
5605         IPackageManager pm = AppGlobals.getPackageManager();
5606
5607         if (changedClasses == null) {
5608             // Nothing changed...
5609             return;
5610         }
5611
5612         // Determine enable/disable state of the package and its components.
5613         int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5614         for (int i = changedClasses.length - 1; i >= 0; i--) {
5615             final String changedClass = changedClasses[i];
5616
5617             if (changedClass.equals(packageName)) {
5618                 try {
5619                     // Entire package setting changed
5620                     enabled = pm.getApplicationEnabledSetting(packageName,
5621                             (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_OWNER);
5622                 } catch (Exception e) {
5623                     // No such package/component; probably racing with uninstall.  In any
5624                     // event it means we have nothing further to do here.
5625                     return;
5626                 }
5627                 packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5628                         && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5629                 if (packageDisabled) {
5630                     // Entire package is disabled.
5631                     // No need to continue to check component states.
5632                     disabledClasses = null;
5633                     break;
5634                 }
5635             } else {
5636                 try {
5637                     enabled = pm.getComponentEnabledSetting(
5638                             new ComponentName(packageName, changedClass),
5639                             (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_OWNER);
5640                 } catch (Exception e) {
5641                     // As above, probably racing with uninstall.
5642                     return;
5643                 }
5644                 if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5645                         && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
5646                     if (disabledClasses == null) {
5647                         disabledClasses = new ArraySet<>(changedClasses.length);
5648                     }
5649                     disabledClasses.add(changedClass);
5650                 }
5651             }
5652         }
5653
5654         if (!packageDisabled && disabledClasses == null) {
5655             // Nothing to do here...
5656             return;
5657         }
5658
5659         // Clean-up disabled activities.
5660         if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
5661                 packageName, disabledClasses, true, false, userId) && mBooted) {
5662             mStackSupervisor.resumeTopActivitiesLocked();
5663             mStackSupervisor.scheduleIdleLocked();
5664         }
5665
5666         // Clean-up disabled tasks
5667         cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
5668
5669         // Clean-up disabled services.
5670         mServices.bringDownDisabledPackageServicesLocked(
5671                 packageName, disabledClasses, userId, false, killProcess, true);
5672
5673         // Clean-up disabled providers.
5674         ArrayList<ContentProviderRecord> providers = new ArrayList<>();
5675         mProviderMap.collectPackageProvidersLocked(
5676                 packageName, disabledClasses, true, false, userId, providers);
5677         for (int i = providers.size() - 1; i >= 0; i--) {
5678             removeDyingProviderLocked(null, providers.get(i), true);
5679         }
5680
5681         // Clean-up disabled broadcast receivers.
5682         for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
5683             mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
5684                     packageName, disabledClasses, userId, true);
5685         }
5686
5687     }
5688
5689     private final boolean forceStopPackageLocked(String packageName, int appId,
5690             boolean callerWillRestart, boolean purgeCache, boolean doit,
5691             boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5692         int i;
5693
5694         if (userId == UserHandle.USER_ALL && packageName == null) {
5695             Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5696         }
5697
5698         if (appId < 0 && packageName != null) {
5699             try {
5700                 appId = UserHandle.getAppId(
5701                         AppGlobals.getPackageManager().getPackageUid(packageName, 0));
5702             } catch (RemoteException e) {
5703             }
5704         }
5705
5706         if (doit) {
5707             if (packageName != null) {
5708                 Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
5709                         + " user=" + userId + ": " + reason);
5710             } else {
5711                 Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5712             }
5713
5714             final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5715             for (int ip = pmap.size() - 1; ip >= 0; ip--) {
5716                 SparseArray<Long> ba = pmap.valueAt(ip);
5717                 for (i = ba.size() - 1; i >= 0; i--) {
5718                     boolean remove = false;
5719                     final int entUid = ba.keyAt(i);
5720                     if (packageName != null) {
5721                         if (userId == UserHandle.USER_ALL) {
5722                             if (UserHandle.getAppId(entUid) == appId) {
5723                                 remove = true;
5724                             }
5725                         } else {
5726                             if (entUid == UserHandle.getUid(userId, appId)) {
5727                                 remove = true;
5728                             }
5729                         }
5730                     } else if (UserHandle.getUserId(entUid) == userId) {
5731                         remove = true;
5732                     }
5733                     if (remove) {
5734                         ba.removeAt(i);
5735                     }
5736                 }
5737                 if (ba.size() == 0) {
5738                     pmap.removeAt(ip);
5739                 }
5740             }
5741         }
5742
5743         boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
5744                 -100, callerWillRestart, true, doit, evenPersistent,
5745                 packageName == null ? ("stop user " + userId) : ("stop " + packageName));
5746
5747         if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
5748                 packageName, null, doit, evenPersistent, userId)) {
5749             if (!doit) {
5750                 return true;
5751             }
5752             didSomething = true;
5753         }
5754
5755         if (mServices.bringDownDisabledPackageServicesLocked(
5756                 packageName, null, userId, evenPersistent, true, doit)) {
5757             if (!doit) {
5758                 return true;
5759             }
5760             didSomething = true;
5761         }
5762
5763         if (packageName == null) {
5764             // Remove all sticky broadcasts from this user.
5765             mStickyBroadcasts.remove(userId);
5766         }
5767
5768         ArrayList<ContentProviderRecord> providers = new ArrayList<>();
5769         if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
5770                 userId, providers)) {
5771             if (!doit) {
5772                 return true;
5773             }
5774             didSomething = true;
5775         }
5776         for (i = providers.size() - 1; i >= 0; i--) {
5777             removeDyingProviderLocked(null, providers.get(i), true);
5778         }
5779
5780         // Remove transient permissions granted from/to this package/user
5781         removeUriPermissionsForPackageLocked(packageName, userId, false);
5782
5783         if (doit) {
5784             for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
5785                 didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
5786                         packageName, null, userId, doit);
5787             }
5788         }
5789
5790         if (packageName == null || uninstalling) {
5791             // Remove pending intents.  For now we only do this when force
5792             // stopping users, because we have some problems when doing this
5793             // for packages -- app widgets are not currently cleaned up for
5794             // such packages, so they can be left with bad pending intents.
5795             if (mIntentSenderRecords.size() > 0) {
5796                 Iterator<WeakReference<PendingIntentRecord>> it
5797                         = mIntentSenderRecords.values().iterator();
5798                 while (it.hasNext()) {
5799                     WeakReference<PendingIntentRecord> wpir = it.next();
5800                     if (wpir == null) {
5801                         it.remove();
5802                         continue;
5803                     }
5804                     PendingIntentRecord pir = wpir.get();
5805                     if (pir == null) {
5806                         it.remove();
5807                         continue;
5808                     }
5809                     if (packageName == null) {
5810                         // Stopping user, remove all objects for the user.
5811                         if (pir.key.userId != userId) {
5812                             // Not the same user, skip it.
5813                             continue;
5814                         }
5815                     } else {
5816                         if (UserHandle.getAppId(pir.uid) != appId) {
5817                             // Different app id, skip it.
5818                             continue;
5819                         }
5820                         if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5821                             // Different user, skip it.
5822                             continue;
5823                         }
5824                         if (!pir.key.packageName.equals(packageName)) {
5825                             // Different package, skip it.
5826                             continue;
5827                         }
5828                     }
5829                     if (!doit) {
5830                         return true;
5831                     }
5832                     didSomething = true;
5833                     it.remove();
5834                     pir.canceled = true;
5835                     if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
5836                         pir.key.activity.pendingResults.remove(pir.ref);
5837                     }
5838                 }
5839             }
5840         }
5841
5842         if (doit) {
5843             if (purgeCache && packageName != null) {
5844                 AttributeCache ac = AttributeCache.instance();
5845                 if (ac != null) {
5846                     ac.removePackage(packageName);
5847                 }
5848             }
5849             if (mBooted) {
5850                 mStackSupervisor.resumeTopActivitiesLocked();
5851                 mStackSupervisor.scheduleIdleLocked();
5852             }
5853         }
5854
5855         return didSomething;
5856     }
5857
5858     private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
5859         ProcessRecord old = mProcessNames.remove(name, uid);
5860         if (old != null) {
5861             old.uidRecord.numProcs--;
5862             if (old.uidRecord.numProcs == 0) {
5863                 // No more processes using this uid, tell clients it is gone.
5864                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
5865                         "No more processes in " + old.uidRecord);
5866                 enqueueUidChangeLocked(old.uidRecord, true);
5867                 mActiveUids.remove(uid);
5868             }
5869             old.uidRecord = null;
5870         }
5871         mIsolatedProcesses.remove(uid);
5872         return old;
5873     }
5874
5875     private final void addProcessNameLocked(ProcessRecord proc) {
5876         // We shouldn't already have a process under this name, but just in case we
5877         // need to clean up whatever may be there now.
5878         ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
5879         if (old == proc && proc.persistent) {
5880             // We are re-adding a persistent process.  Whatevs!  Just leave it there.
5881             Slog.w(TAG, "Re-adding persistent process " + proc);
5882         } else if (old != null) {
5883             Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
5884         }
5885         UidRecord uidRec = mActiveUids.get(proc.uid);
5886         if (uidRec == null) {
5887             uidRec = new UidRecord(proc.uid);
5888             // This is the first appearance of the uid, report it now!
5889             if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
5890                     "Creating new process uid: " + uidRec);
5891             mActiveUids.put(proc.uid, uidRec);
5892             enqueueUidChangeLocked(uidRec, false);
5893         }
5894         proc.uidRecord = uidRec;
5895         uidRec.numProcs++;
5896         mProcessNames.put(proc.processName, proc.uid, proc);
5897         if (proc.isolated) {
5898             mIsolatedProcesses.put(proc.uid, proc);
5899         }
5900     }
5901
5902     private final boolean removeProcessLocked(ProcessRecord app,
5903             boolean callerWillRestart, boolean allowRestart, String reason) {
5904         final String name = app.processName;
5905         final int uid = app.uid;
5906         if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
5907             "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
5908
5909         removeProcessNameLocked(name, uid);
5910         if (mHeavyWeightProcess == app) {
5911             mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5912                     mHeavyWeightProcess.userId, 0));
5913             mHeavyWeightProcess = null;
5914         }
5915         boolean needRestart = false;
5916         if (app.pid > 0 && app.pid != MY_PID) {
5917             int pid = app.pid;
5918             synchronized (mPidsSelfLocked) {
5919                 mPidsSelfLocked.remove(pid);
5920                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5921             }
5922             mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5923             if (app.isolated) {
5924                 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5925             }
5926             boolean willRestart = false;
5927             if (app.persistent && !app.isolated) {
5928                 if (!callerWillRestart) {
5929                     willRestart = true;
5930                 } else {
5931                     needRestart = true;
5932                 }
5933             }
5934             app.kill(reason, true);
5935             handleAppDiedLocked(app, willRestart, allowRestart);
5936             if (willRestart) {
5937                 removeLruProcessLocked(app);
5938                 addAppLocked(app.info, false, null /* ABI override */);
5939             }
5940         } else {
5941             mRemovedProcesses.add(app);
5942         }
5943
5944         return needRestart;
5945     }
5946
5947     private final void processStartTimedOutLocked(ProcessRecord app) {
5948         final int pid = app.pid;
5949         boolean gone = false;
5950         synchronized (mPidsSelfLocked) {
5951             ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5952             if (knownApp != null && knownApp.thread == null) {
5953                 mPidsSelfLocked.remove(pid);
5954                 gone = true;
5955             }
5956         }
5957
5958         if (gone) {
5959             Slog.w(TAG, "Process " + app + " failed to attach");
5960             EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5961                     pid, app.uid, app.processName);
5962             removeProcessNameLocked(app.processName, app.uid);
5963             if (mHeavyWeightProcess == app) {
5964                 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5965                         mHeavyWeightProcess.userId, 0));
5966                 mHeavyWeightProcess = null;
5967             }
5968             mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5969             if (app.isolated) {
5970                 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5971             }
5972             // Take care of any launching providers waiting for this process.
5973             checkAppInLaunchingProvidersLocked(app, true);
5974             // Take care of any services that are waiting for the process.
5975             mServices.processStartTimedOutLocked(app);
5976             app.kill("start timeout", true);
5977             removeLruProcessLocked(app);
5978             if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5979                 Slog.w(TAG, "Unattached app died before backup, skipping");
5980                 try {
5981                     IBackupManager bm = IBackupManager.Stub.asInterface(
5982                             ServiceManager.getService(Context.BACKUP_SERVICE));
5983                     bm.agentDisconnected(app.info.packageName);
5984                 } catch (RemoteException e) {
5985                     // Can't happen; the backup manager is local
5986                 }
5987             }
5988             if (isPendingBroadcastProcessLocked(pid)) {
5989                 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5990                 skipPendingBroadcastLocked(pid);
5991             }
5992         } else {
5993             Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5994         }
5995     }
5996
5997     private final boolean attachApplicationLocked(IApplicationThread thread,
5998             int pid) {
5999
6000         // Find the application record that is being attached...  either via
6001         // the pid if we are running in multiple processes, or just pull the
6002         // next app record if we are emulating process with anonymous threads.
6003         ProcessRecord app;
6004         if (pid != MY_PID && pid >= 0) {
6005             synchronized (mPidsSelfLocked) {
6006                 app = mPidsSelfLocked.get(pid);
6007             }
6008         } else {
6009             app = null;
6010         }
6011
6012         if (app == null) {
6013             Slog.w(TAG, "No pending application record for pid " + pid
6014                     + " (IApplicationThread " + thread + "); dropping process");
6015             EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6016             if (pid > 0 && pid != MY_PID) {
6017                 Process.killProcessQuiet(pid);
6018                 //TODO: killProcessGroup(app.info.uid, pid);
6019             } else {
6020                 try {
6021                     thread.scheduleExit();
6022                 } catch (Exception e) {
6023                     // Ignore exceptions.
6024                 }
6025             }
6026             return false;
6027         }
6028
6029         // If this application record is still attached to a previous
6030         // process, clean it up now.
6031         if (app.thread != null) {
6032             handleAppDiedLocked(app, true, true);
6033         }
6034
6035         // Tell the process all about itself.
6036
6037         if (DEBUG_ALL) Slog.v(
6038                 TAG, "Binding process pid " + pid + " to record " + app);
6039
6040         final String processName = app.processName;
6041         try {
6042             AppDeathRecipient adr = new AppDeathRecipient(
6043                     app, pid, thread);
6044             thread.asBinder().linkToDeath(adr, 0);
6045             app.deathRecipient = adr;
6046         } catch (RemoteException e) {
6047             app.resetPackageList(mProcessStats);
6048             startProcessLocked(app, "link fail", processName);
6049             return false;
6050         }
6051
6052         EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6053
6054         app.makeActive(thread, mProcessStats);
6055         app.curAdj = app.setAdj = -100;
6056         app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
6057         app.forcingToForeground = null;
6058         updateProcessForegroundLocked(app, false, false);
6059         app.hasShownUi = false;
6060         app.debugging = false;
6061         app.cached = false;
6062         app.killedByAm = false;
6063
6064         mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6065
6066         boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6067         List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6068
6069         if (!normalMode) {
6070             Slog.i(TAG, "Launching preboot mode app: " + app);
6071         }
6072
6073         if (DEBUG_ALL) Slog.v(
6074             TAG, "New app record " + app
6075             + " thread=" + thread.asBinder() + " pid=" + pid);
6076         try {
6077             int testMode = IApplicationThread.DEBUG_OFF;
6078             if (mDebugApp != null && mDebugApp.equals(processName)) {
6079                 testMode = mWaitForDebugger
6080                     ? IApplicationThread.DEBUG_WAIT
6081                     : IApplicationThread.DEBUG_ON;
6082                 app.debugging = true;
6083                 if (mDebugTransient) {
6084                     mDebugApp = mOrigDebugApp;
6085                     mWaitForDebugger = mOrigWaitForDebugger;
6086                 }
6087             }
6088             String profileFile = app.instrumentationProfileFile;
6089             ParcelFileDescriptor profileFd = null;
6090             int samplingInterval = 0;
6091             boolean profileAutoStop = false;
6092             if (mProfileApp != null && mProfileApp.equals(processName)) {
6093                 mProfileProc = app;
6094                 profileFile = mProfileFile;
6095                 profileFd = mProfileFd;
6096                 samplingInterval = mSamplingInterval;
6097                 profileAutoStop = mAutoStopProfiler;
6098             }
6099             boolean enableOpenGlTrace = false;
6100             if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
6101                 enableOpenGlTrace = true;
6102                 mOpenGlTraceApp = null;
6103             }
6104
6105             // If the app is being launched for restore or full backup, set it up specially
6106             boolean isRestrictedBackupMode = false;
6107             if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6108                 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
6109                         || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6110                         || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
6111             }
6112
6113             ensurePackageDexOpt(app.instrumentationInfo != null
6114                     ? app.instrumentationInfo.packageName
6115                     : app.info.packageName);
6116             if (app.instrumentationClass != null) {
6117                 ensurePackageDexOpt(app.instrumentationClass.getPackageName());
6118             }
6119             if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
6120                     + processName + " with config " + mConfiguration);
6121             ApplicationInfo appInfo = app.instrumentationInfo != null
6122                     ? app.instrumentationInfo : app.info;
6123             app.compat = compatibilityInfoForPackageLocked(appInfo);
6124             if (profileFd != null) {
6125                 profileFd = profileFd.dup();
6126             }
6127             ProfilerInfo profilerInfo = profileFile == null ? null
6128                     : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6129             thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6130                     profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6131                     app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
6132                     isRestrictedBackupMode || !normalMode, app.persistent,
6133                     new Configuration(mConfiguration), app.compat,
6134                     getCommonServicesLocked(app.isolated),
6135                     mCoreSettingsObserver.getCoreSettingsLocked());
6136             updateLruProcessLocked(app, false, null);
6137             app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6138         } catch (Exception e) {
6139             // todo: Yikes!  What should we do?  For now we will try to
6140             // start another process, but that could easily get us in
6141             // an infinite loop of restarting processes...
6142             Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6143
6144             app.resetPackageList(mProcessStats);
6145             app.unlinkDeathRecipient();
6146             startProcessLocked(app, "bind fail", processName);
6147             return false;
6148         }
6149
6150         // Remove this record from the list of starting applications.
6151         mPersistentStartingProcesses.remove(app);
6152         if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
6153                 "Attach application locked removing on hold: " + app);
6154         mProcessesOnHold.remove(app);
6155
6156         boolean badApp = false;
6157         boolean didSomething = false;
6158
6159         // See if the top visible activity is waiting to run in this process...
6160         if (normalMode) {
6161             try {
6162                 if (mStackSupervisor.attachApplicationLocked(app)) {
6163                     didSomething = true;
6164                 }
6165             } catch (Exception e) {
6166                 Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6167                 badApp = true;
6168             }
6169         }
6170
6171         // Find any services that should be running in this process...
6172         if (!badApp) {
6173             try {
6174                 didSomething |= mServices.attachApplicationLocked(app, processName);
6175             } catch (Exception e) {
6176                 Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6177                 badApp = true;
6178             }
6179         }
6180
6181         // Check if a next-broadcast receiver is in this process...
6182         if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6183             try {
6184                 didSomething |= sendPendingBroadcastsLocked(app);
6185             } catch (Exception e) {
6186                 // If the app died trying to launch the receiver we declare it 'bad'
6187                 Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6188                 badApp = true;
6189             }
6190         }
6191
6192         // Check whether the next backup agent is in this process...
6193         if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6194             if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
6195                     "New app is backup target, launching agent for " + app);
6196             ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
6197             try {
6198                 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6199                         compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6200                         mBackupTarget.backupMode);
6201             } catch (Exception e) {
6202                 Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6203                 badApp = true;
6204             }
6205         }
6206
6207         if (badApp) {
6208             app.kill("error during init", true);
6209             handleAppDiedLocked(app, false, true);
6210             return false;
6211         }
6212
6213         if (!didSomething) {
6214             updateOomAdjLocked();
6215         }
6216
6217         return true;
6218     }
6219
6220     @Override
6221     public final void attachApplication(IApplicationThread thread) {
6222         synchronized (this) {
6223             int callingPid = Binder.getCallingPid();
6224             final long origId = Binder.clearCallingIdentity();
6225             attachApplicationLocked(thread, callingPid);
6226             Binder.restoreCallingIdentity(origId);
6227         }
6228     }
6229
6230     @Override
6231     public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6232         final long origId = Binder.clearCallingIdentity();
6233         synchronized (this) {
6234             ActivityStack stack = ActivityRecord.getStackLocked(token);
6235             if (stack != null) {
6236                 ActivityRecord r =
6237                         mStackSupervisor.activityIdleInternalLocked(token, false, config);
6238                 if (stopProfiling) {
6239                     if ((mProfileProc == r.app) && (mProfileFd != null)) {
6240                         try {
6241                             mProfileFd.close();
6242                         } catch (IOException e) {
6243                         }
6244                         clearProfilerLocked();
6245                     }
6246                 }
6247             }
6248         }
6249         Binder.restoreCallingIdentity(origId);
6250     }
6251
6252     void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6253         mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6254                 finishBooting ? 1 : 0, enableScreen ? 1 : 0));
6255     }
6256
6257     void enableScreenAfterBoot() {
6258         EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6259                 SystemClock.uptimeMillis());
6260         mWindowManager.enableScreenAfterBoot();
6261
6262         synchronized (this) {
6263             updateEventDispatchingLocked();
6264         }
6265     }
6266
6267     @Override
6268     public void showBootMessage(final CharSequence msg, final boolean always) {
6269         if (Binder.getCallingUid() != Process.myUid()) {
6270             // These days only the core system can call this, so apps can't get in
6271             // the way of what we show about running them.
6272         }
6273         mWindowManager.showBootMessage(msg, always);
6274     }
6275
6276     @Override
6277     public void keyguardWaitingForActivityDrawn() {
6278         enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6279         final long token = Binder.clearCallingIdentity();
6280         try {
6281             synchronized (this) {
6282                 if (DEBUG_LOCKSCREEN) logLockScreen("");
6283                 mWindowManager.keyguardWaitingForActivityDrawn();
6284                 if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6285                     mLockScreenShown = LOCK_SCREEN_LEAVING;
6286                     updateSleepIfNeededLocked();
6287                 }
6288             }
6289         } finally {
6290             Binder.restoreCallingIdentity(token);
6291         }
6292     }
6293
6294     @Override
6295     public void keyguardGoingAway(boolean disableWindowAnimations,
6296             boolean keyguardGoingToNotificationShade) {
6297         enforceNotIsolatedCaller("keyguardGoingAway");
6298         final long token = Binder.clearCallingIdentity();
6299         try {
6300             synchronized (this) {
6301                 if (DEBUG_LOCKSCREEN) logLockScreen("");
6302                 mWindowManager.keyguardGoingAway(disableWindowAnimations,
6303                         keyguardGoingToNotificationShade);
6304                 if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6305                     mLockScreenShown = LOCK_SCREEN_HIDDEN;
6306                     updateSleepIfNeededLocked();
6307                 }
6308             }
6309         } finally {
6310             Binder.restoreCallingIdentity(token);
6311         }
6312     }
6313
6314     final void finishBooting() {
6315         synchronized (this) {
6316             if (!mBootAnimationComplete) {
6317                 mCallFinishBooting = true;
6318                 return;
6319             }
6320             mCallFinishBooting = false;
6321         }
6322
6323         ArraySet<String> completedIsas = new ArraySet<String>();
6324         for (String abi : Build.SUPPORTED_ABIS) {
6325             Process.establishZygoteConnectionForAbi(abi);
6326             final String instructionSet = VMRuntime.getInstructionSet(abi);
6327             if (!completedIsas.contains(instructionSet)) {
6328                 if (mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi)) != 0) {
6329                     Slog.e(TAG, "Unable to mark boot complete for abi: " + abi);
6330                 }
6331                 completedIsas.add(instructionSet);
6332             }
6333         }
6334
6335         IntentFilter pkgFilter = new IntentFilter();
6336         pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6337         pkgFilter.addDataScheme("package");
6338         mContext.registerReceiver(new BroadcastReceiver() {
6339             @Override
6340             public void onReceive(Context context, Intent intent) {
6341                 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6342                 if (pkgs != null) {
6343                     for (String pkg : pkgs) {
6344                         synchronized (ActivityManagerService.this) {
6345                             if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6346                                     0, "query restart")) {
6347                                 setResultCode(Activity.RESULT_OK);
6348                                 return;
6349                             }
6350                         }
6351                     }
6352                 }
6353             }
6354         }, pkgFilter);
6355
6356         IntentFilter dumpheapFilter = new IntentFilter();
6357         dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
6358         mContext.registerReceiver(new BroadcastReceiver() {
6359             @Override
6360             public void onReceive(Context context, Intent intent) {
6361                 if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
6362                     mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
6363                 } else {
6364                     mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
6365                 }
6366             }
6367         }, dumpheapFilter);
6368
6369         // Let system services know.
6370         mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6371
6372         synchronized (this) {
6373             // Ensure that any processes we had put on hold are now started
6374             // up.
6375             final int NP = mProcessesOnHold.size();
6376             if (NP > 0) {
6377                 ArrayList<ProcessRecord> procs =
6378                     new ArrayList<ProcessRecord>(mProcessesOnHold);
6379                 for (int ip=0; ip<NP; ip++) {
6380                     if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
6381                             + procs.get(ip));
6382                     startProcessLocked(procs.get(ip), "on-hold", null);
6383                 }
6384             }
6385
6386             if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6387                 // Start looking for apps that are abusing wake locks.
6388                 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6389                 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6390                 // Tell anyone interested that we are done booting!
6391                 SystemProperties.set("sys.boot_completed", "1");
6392
6393                 // And trigger dev.bootcomplete if we are not showing encryption progress
6394                 if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6395                     || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6396                     SystemProperties.set("dev.bootcomplete", "1");
6397                 }
6398                 for (int i=0; i<mStartedUsers.size(); i++) {
6399                     UserState uss = mStartedUsers.valueAt(i);
6400                     if (uss.mState == UserState.STATE_BOOTING) {
6401                         uss.mState = UserState.STATE_RUNNING;
6402                         final int userId = mStartedUsers.keyAt(i);
6403                         Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
6404                         intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
6405                         intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
6406                         broadcastIntentLocked(null, null, intent, null,
6407                                 new IIntentReceiver.Stub() {
6408                                     @Override
6409                                     public void performReceive(Intent intent, int resultCode,
6410                                             String data, Bundle extras, boolean ordered,
6411                                             boolean sticky, int sendingUser) {
6412                                         synchronized (ActivityManagerService.this) {
6413                                             requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6414                                                     true, false);
6415                                         }
6416                                     }
6417                                 },
6418                                 0, null, null,
6419                                 new String[] {android.Manifest.permission.RECEIVE_BOOT_COMPLETED},
6420                                 AppOpsManager.OP_NONE, null, true, false,
6421                                 MY_PID, Process.SYSTEM_UID, userId);
6422                     }
6423                 }
6424                 scheduleStartProfilesLocked();
6425             }
6426         }
6427     }
6428
6429     @Override
6430     public void bootAnimationComplete() {
6431         final boolean callFinishBooting;
6432         synchronized (this) {
6433             callFinishBooting = mCallFinishBooting;
6434             mBootAnimationComplete = true;
6435         }
6436         if (callFinishBooting) {
6437             finishBooting();
6438         }
6439     }
6440
6441     final void ensureBootCompleted() {
6442         boolean booting;
6443         boolean enableScreen;
6444         synchronized (this) {
6445             booting = mBooting;
6446             mBooting = false;
6447             enableScreen = !mBooted;
6448             mBooted = true;
6449         }
6450
6451         if (booting) {
6452             finishBooting();
6453         }
6454
6455         if (enableScreen) {
6456             enableScreenAfterBoot();
6457         }
6458     }
6459
6460     @Override
6461     public final void activityResumed(IBinder token) {
6462         final long origId = Binder.clearCallingIdentity();
6463         synchronized(this) {
6464             ActivityStack stack = ActivityRecord.getStackLocked(token);
6465             if (stack != null) {
6466                 ActivityRecord.activityResumedLocked(token);
6467             }
6468         }
6469         Binder.restoreCallingIdentity(origId);
6470     }
6471
6472     @Override
6473     public final void activityPaused(IBinder token) {
6474         final long origId = Binder.clearCallingIdentity();
6475         synchronized(this) {
6476             ActivityStack stack = ActivityRecord.getStackLocked(token);
6477             if (stack != null) {
6478                 stack.activityPausedLocked(token, false);
6479             }
6480         }
6481         Binder.restoreCallingIdentity(origId);
6482     }
6483
6484     @Override
6485     public final void activityStopped(IBinder token, Bundle icicle,
6486             PersistableBundle persistentState, CharSequence description) {
6487         if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
6488
6489         // Refuse possible leaked file descriptors
6490         if (icicle != null && icicle.hasFileDescriptors()) {
6491             throw new IllegalArgumentException("File descriptors passed in Bundle");
6492         }
6493
6494         final long origId = Binder.clearCallingIdentity();
6495
6496         synchronized (this) {
6497             ActivityRecord r = ActivityRecord.isInStackLocked(token);
6498             if (r != null) {
6499                 r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6500             }
6501         }
6502
6503         trimApplications();
6504
6505         Binder.restoreCallingIdentity(origId);
6506     }
6507
6508     @Override
6509     public final void activityDestroyed(IBinder token) {
6510         if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
6511         synchronized (this) {
6512             ActivityStack stack = ActivityRecord.getStackLocked(token);
6513             if (stack != null) {
6514                 stack.activityDestroyedLocked(token, "activityDestroyed");
6515             }
6516         }
6517     }
6518
6519     @Override
6520     public final void backgroundResourcesReleased(IBinder token) {
6521         final long origId = Binder.clearCallingIdentity();
6522         try {
6523             synchronized (this) {
6524                 ActivityStack stack = ActivityRecord.getStackLocked(token);
6525                 if (stack != null) {
6526                     stack.backgroundResourcesReleased();
6527                 }
6528             }
6529         } finally {
6530             Binder.restoreCallingIdentity(origId);
6531         }
6532     }
6533
6534     @Override
6535     public final void notifyLaunchTaskBehindComplete(IBinder token) {
6536         mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6537     }
6538
6539     @Override
6540     public final void notifyEnterAnimationComplete(IBinder token) {
6541         mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6542     }
6543
6544     @Override
6545     public String getCallingPackage(IBinder token) {
6546         synchronized (this) {
6547             ActivityRecord r = getCallingRecordLocked(token);
6548             return r != null ? r.info.packageName : null;
6549         }
6550     }
6551
6552     @Override
6553     public ComponentName getCallingActivity(IBinder token) {
6554         synchronized (this) {
6555             ActivityRecord r = getCallingRecordLocked(token);
6556             return r != null ? r.intent.getComponent() : null;
6557         }
6558     }
6559
6560     private ActivityRecord getCallingRecordLocked(IBinder token) {
6561         ActivityRecord r = ActivityRecord.isInStackLocked(token);
6562         if (r == null) {
6563             return null;
6564         }
6565         return r.resultTo;
6566     }
6567
6568     @Override
6569     public ComponentName getActivityClassForToken(IBinder token) {
6570         synchronized(this) {
6571             ActivityRecord r = ActivityRecord.isInStackLocked(token);
6572             if (r == null) {
6573                 return null;
6574             }
6575             return r.intent.getComponent();
6576         }
6577     }
6578
6579     @Override
6580     public String getPackageForToken(IBinder token) {
6581         synchronized(this) {
6582             ActivityRecord r = ActivityRecord.isInStackLocked(token);
6583             if (r == null) {
6584                 return null;
6585             }
6586             return r.packageName;
6587         }
6588     }
6589
6590     @Override
6591     public boolean isRootVoiceInteraction(IBinder token) {
6592         synchronized(this) {
6593             ActivityRecord r = ActivityRecord.isInStackLocked(token);
6594             if (r == null) {
6595                 return false;
6596             }
6597             return r.rootVoiceInteraction;
6598         }
6599     }
6600
6601     @Override
6602     public IIntentSender getIntentSender(int type,
6603             String packageName, IBinder token, String resultWho,
6604             int requestCode, Intent[] intents, String[] resolvedTypes,
6605             int flags, Bundle options, int userId) {
6606         enforceNotIsolatedCaller("getIntentSender");
6607         // Refuse possible leaked file descriptors
6608         if (intents != null) {
6609             if (intents.length < 1) {
6610                 throw new IllegalArgumentException("Intents array length must be >= 1");
6611             }
6612             for (int i=0; i<intents.length; i++) {
6613                 Intent intent = intents[i];
6614                 if (intent != null) {
6615                     if (intent.hasFileDescriptors()) {
6616                         throw new IllegalArgumentException("File descriptors passed in Intent");
6617                     }
6618                     if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6619                             (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6620                         throw new IllegalArgumentException(
6621                                 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6622                     }
6623                     intents[i] = new Intent(intent);
6624                 }
6625             }
6626             if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6627                 throw new IllegalArgumentException(
6628                         "Intent array length does not match resolvedTypes length");
6629             }
6630         }
6631         if (options != null) {
6632             if (options.hasFileDescriptors()) {
6633                 throw new IllegalArgumentException("File descriptors passed in options");
6634             }
6635         }
6636
6637         synchronized(this) {
6638             int callingUid = Binder.getCallingUid();
6639             int origUserId = userId;
6640             userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6641                     type == ActivityManager.INTENT_SENDER_BROADCAST,
6642                     ALLOW_NON_FULL, "getIntentSender", null);
6643             if (origUserId == UserHandle.USER_CURRENT) {
6644                 // We don't want to evaluate this until the pending intent is
6645                 // actually executed.  However, we do want to always do the
6646                 // security checking for it above.
6647                 userId = UserHandle.USER_CURRENT;
6648             }
6649             try {
6650                 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6651                     int uid = AppGlobals.getPackageManager()
6652                             .getPackageUid(packageName, UserHandle.getUserId(callingUid));
6653                     if (!UserHandle.isSameApp(callingUid, uid)) {
6654                         String msg = "Permission Denial: getIntentSender() from pid="
6655                             + Binder.getCallingPid()
6656                             + ", uid=" + Binder.getCallingUid()
6657                             + ", (need uid=" + uid + ")"
6658                             + " is not allowed to send as package " + packageName;
6659                         Slog.w(TAG, msg);
6660                         throw new SecurityException(msg);
6661                     }
6662                 }
6663
6664                 return getIntentSenderLocked(type, packageName, callingUid, userId,
6665                         token, resultWho, requestCode, intents, resolvedTypes, flags, options);
6666
6667             } catch (RemoteException e) {
6668                 throw new SecurityException(e);
6669             }
6670         }
6671     }
6672
6673     IIntentSender getIntentSenderLocked(int type, String packageName,
6674             int callingUid, int userId, IBinder token, String resultWho,
6675             int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6676             Bundle options) {
6677         if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6678         ActivityRecord activity = null;
6679         if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6680             activity = ActivityRecord.isInStackLocked(token);
6681             if (activity == null) {
6682                 return null;
6683             }
6684             if (activity.finishing) {
6685                 return null;
6686             }
6687         }
6688
6689         final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6690         final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6691         final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6692         flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6693                 |PendingIntent.FLAG_UPDATE_CURRENT);
6694
6695         PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6696                 type, packageName, activity, resultWho,
6697                 requestCode, intents, resolvedTypes, flags, options, userId);
6698         WeakReference<PendingIntentRecord> ref;
6699         ref = mIntentSenderRecords.get(key);
6700         PendingIntentRecord rec = ref != null ? ref.get() : null;
6701         if (rec != null) {
6702             if (!cancelCurrent) {
6703                 if (updateCurrent) {
6704                     if (rec.key.requestIntent != null) {
6705                         rec.key.requestIntent.replaceExtras(intents != null ?
6706                                 intents[intents.length - 1] : null);
6707                     }
6708                     if (intents != null) {
6709                         intents[intents.length-1] = rec.key.requestIntent;
6710                         rec.key.allIntents = intents;
6711                         rec.key.allResolvedTypes = resolvedTypes;
6712                     } else {
6713                         rec.key.allIntents = null;
6714                         rec.key.allResolvedTypes = null;
6715                     }
6716                 }
6717                 return rec;
6718             }
6719             rec.canceled = true;
6720             mIntentSenderRecords.remove(key);
6721         }
6722         if (noCreate) {
6723             return rec;
6724         }
6725         rec = new PendingIntentRecord(this, key, callingUid);
6726         mIntentSenderRecords.put(key, rec.ref);
6727         if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6728             if (activity.pendingResults == null) {
6729                 activity.pendingResults
6730                         = new HashSet<WeakReference<PendingIntentRecord>>();
6731             }
6732             activity.pendingResults.add(rec.ref);
6733         }
6734         return rec;
6735     }
6736
6737     @Override
6738     public void cancelIntentSender(IIntentSender sender) {
6739         if (!(sender instanceof PendingIntentRecord)) {
6740             return;
6741         }
6742         synchronized(this) {
6743             PendingIntentRecord rec = (PendingIntentRecord)sender;
6744             try {
6745                 int uid = AppGlobals.getPackageManager()
6746                         .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
6747                 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6748                     String msg = "Permission Denial: cancelIntentSender() from pid="
6749                         + Binder.getCallingPid()
6750                         + ", uid=" + Binder.getCallingUid()
6751                         + " is not allowed to cancel packges "
6752                         + rec.key.packageName;
6753                     Slog.w(TAG, msg);
6754                     throw new SecurityException(msg);
6755                 }
6756             } catch (RemoteException e) {
6757                 throw new SecurityException(e);
6758             }
6759             cancelIntentSenderLocked(rec, true);
6760         }
6761     }
6762
6763     void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
6764         rec.canceled = true;
6765         mIntentSenderRecords.remove(rec.key);
6766         if (cleanActivity && rec.key.activity != null) {
6767             rec.key.activity.pendingResults.remove(rec.ref);
6768         }
6769     }
6770
6771     @Override
6772     public String getPackageForIntentSender(IIntentSender pendingResult) {
6773         if (!(pendingResult instanceof PendingIntentRecord)) {
6774             return null;
6775         }
6776         try {
6777             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6778             return res.key.packageName;
6779         } catch (ClassCastException e) {
6780         }
6781         return null;
6782     }
6783
6784     @Override
6785     public int getUidForIntentSender(IIntentSender sender) {
6786         if (sender instanceof PendingIntentRecord) {
6787             try {
6788                 PendingIntentRecord res = (PendingIntentRecord)sender;
6789                 return res.uid;
6790             } catch (ClassCastException e) {
6791             }
6792         }
6793         return -1;
6794     }
6795
6796     @Override
6797     public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
6798         if (!(pendingResult instanceof PendingIntentRecord)) {
6799             return false;
6800         }
6801         try {
6802             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6803             if (res.key.allIntents == null) {
6804                 return false;
6805             }
6806             for (int i=0; i<res.key.allIntents.length; i++) {
6807                 Intent intent = res.key.allIntents[i];
6808                 if (intent.getPackage() != null && intent.getComponent() != null) {
6809                     return false;
6810                 }
6811             }
6812             return true;
6813         } catch (ClassCastException e) {
6814         }
6815         return false;
6816     }
6817
6818     @Override
6819     public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
6820         if (!(pendingResult instanceof PendingIntentRecord)) {
6821             return false;
6822         }
6823         try {
6824             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6825             if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6826                 return true;
6827             }
6828             return false;
6829         } catch (ClassCastException e) {
6830         }
6831         return false;
6832     }
6833
6834     @Override
6835     public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6836         if (!(pendingResult instanceof PendingIntentRecord)) {
6837             return null;
6838         }
6839         try {
6840             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6841             return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6842         } catch (ClassCastException e) {
6843         }
6844         return null;
6845     }
6846
6847     @Override
6848     public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6849         if (!(pendingResult instanceof PendingIntentRecord)) {
6850             return null;
6851         }
6852         try {
6853             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6854             synchronized (this) {
6855                 return getTagForIntentSenderLocked(res, prefix);
6856             }
6857         } catch (ClassCastException e) {
6858         }
6859         return null;
6860     }
6861
6862     String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
6863         final Intent intent = res.key.requestIntent;
6864         if (intent != null) {
6865             if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6866                     || res.lastTagPrefix.equals(prefix))) {
6867                 return res.lastTag;
6868             }
6869             res.lastTagPrefix = prefix;
6870             final StringBuilder sb = new StringBuilder(128);
6871             if (prefix != null) {
6872                 sb.append(prefix);
6873             }
6874             if (intent.getAction() != null) {
6875                 sb.append(intent.getAction());
6876             } else if (intent.getComponent() != null) {
6877                 intent.getComponent().appendShortString(sb);
6878             } else {
6879                 sb.append("?");
6880             }
6881             return res.lastTag = sb.toString();
6882         }
6883         return null;
6884     }
6885
6886     @Override
6887     public void setProcessLimit(int max) {
6888         enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6889                 "setProcessLimit()");
6890         synchronized (this) {
6891             mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6892             mProcessLimitOverride = max;
6893         }
6894         trimApplications();
6895     }
6896
6897     @Override
6898     public int getProcessLimit() {
6899         synchronized (this) {
6900             return mProcessLimitOverride;
6901         }
6902     }
6903
6904     void foregroundTokenDied(ForegroundToken token) {
6905         synchronized (ActivityManagerService.this) {
6906             synchronized (mPidsSelfLocked) {
6907                 ForegroundToken cur
6908                     = mForegroundProcesses.get(token.pid);
6909                 if (cur != token) {
6910                     return;
6911                 }
6912                 mForegroundProcesses.remove(token.pid);
6913                 ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6914                 if (pr == null) {
6915                     return;
6916                 }
6917                 pr.forcingToForeground = null;
6918                 updateProcessForegroundLocked(pr, false, false);
6919             }
6920             updateOomAdjLocked();
6921         }
6922     }
6923
6924     @Override
6925     public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6926         enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6927                 "setProcessForeground()");
6928         synchronized(this) {
6929             boolean changed = false;
6930
6931             synchronized (mPidsSelfLocked) {
6932                 ProcessRecord pr = mPidsSelfLocked.get(pid);
6933                 if (pr == null && isForeground) {
6934                     Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6935                     return;
6936                 }
6937                 ForegroundToken oldToken = mForegroundProcesses.get(pid);
6938                 if (oldToken != null) {
6939                     oldToken.token.unlinkToDeath(oldToken, 0);
6940                     mForegroundProcesses.remove(pid);
6941                     if (pr != null) {
6942                         pr.forcingToForeground = null;
6943                     }
6944                     changed = true;
6945                 }
6946                 if (isForeground && token != null) {
6947                     ForegroundToken newToken = new ForegroundToken() {
6948                         @Override
6949                         public void binderDied() {
6950                             foregroundTokenDied(this);
6951                         }
6952                     };
6953                     newToken.pid = pid;
6954                     newToken.token = token;
6955                     try {
6956                         token.linkToDeath(newToken, 0);
6957                         mForegroundProcesses.put(pid, newToken);
6958                         pr.forcingToForeground = token;
6959                         changed = true;
6960                     } catch (RemoteException e) {
6961                         // If the process died while doing this, we will later
6962                         // do the cleanup with the process death link.
6963                     }
6964                 }
6965             }
6966
6967             if (changed) {
6968                 updateOomAdjLocked();
6969             }
6970         }
6971     }
6972
6973     // =========================================================
6974     // PROCESS INFO
6975     // =========================================================
6976
6977     static class ProcessInfoService extends IProcessInfoService.Stub {
6978         final ActivityManagerService mActivityManagerService;
6979         ProcessInfoService(ActivityManagerService activityManagerService) {
6980             mActivityManagerService = activityManagerService;
6981         }
6982
6983         @Override
6984         public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
6985             mActivityManagerService.getProcessStatesForPIDs(/*in*/ pids, /*out*/ states);
6986         }
6987     }
6988
6989     /**
6990      * For each PID in the given input array, write the current process state
6991      * for that process into the output array, or -1 to indicate that no
6992      * process with the given PID exists.
6993      */
6994     public void getProcessStatesForPIDs(/*in*/ int[] pids, /*out*/ int[] states) {
6995         if (pids == null) {
6996             throw new NullPointerException("pids");
6997         } else if (states == null) {
6998             throw new NullPointerException("states");
6999         } else if (pids.length != states.length) {
7000             throw new IllegalArgumentException("input and output arrays have different lengths!");
7001         }
7002
7003         synchronized (mPidsSelfLocked) {
7004             for (int i = 0; i < pids.length; i++) {
7005                 ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
7006                 states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
7007                         pr.curProcState;
7008             }
7009         }
7010     }
7011
7012     // =========================================================
7013     // PERMISSIONS
7014     // =========================================================
7015
7016     static class PermissionController extends IPermissionController.Stub {
7017         ActivityManagerService mActivityManagerService;
7018         PermissionController(ActivityManagerService activityManagerService) {
7019             mActivityManagerService = activityManagerService;
7020         }
7021
7022         @Override
7023         public boolean checkPermission(String permission, int pid, int uid) {
7024             return mActivityManagerService.checkPermission(permission, pid,
7025                     uid) == PackageManager.PERMISSION_GRANTED;
7026         }
7027
7028         @Override
7029         public String[] getPackagesForUid(int uid) {
7030             return mActivityManagerService.mContext.getPackageManager()
7031                     .getPackagesForUid(uid);
7032         }
7033
7034         @Override
7035         public boolean isRuntimePermission(String permission) {
7036             try {
7037                 PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
7038                         .getPermissionInfo(permission, 0);
7039                 return info.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS;
7040             } catch (NameNotFoundException nnfe) {
7041                 Slog.e(TAG, "No such permission: "+ permission, nnfe);
7042             }
7043             return false;
7044         }
7045     }
7046
7047     class IntentFirewallInterface implements IntentFirewall.AMSInterface {
7048         @Override
7049         public int checkComponentPermission(String permission, int pid, int uid,
7050                 int owningUid, boolean exported) {
7051             return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
7052                     owningUid, exported);
7053         }
7054
7055         @Override
7056         public Object getAMSLock() {
7057             return ActivityManagerService.this;
7058         }
7059     }
7060
7061     /**
7062      * This can be called with or without the global lock held.
7063      */
7064     int checkComponentPermission(String permission, int pid, int uid,
7065             int owningUid, boolean exported) {
7066         if (pid == MY_PID) {
7067             return PackageManager.PERMISSION_GRANTED;
7068         }
7069         return ActivityManager.checkComponentPermission(permission, uid,
7070                 owningUid, exported);
7071     }
7072
7073     /**
7074      * As the only public entry point for permissions checking, this method
7075      * can enforce the semantic that requesting a check on a null global
7076      * permission is automatically denied.  (Internally a null permission
7077      * string is used when calling {@link #checkComponentPermission} in cases
7078      * when only uid-based security is needed.)
7079      *
7080      * This can be called with or without the global lock held.
7081      */
7082     @Override
7083     public int checkPermission(String permission, int pid, int uid) {
7084         if (permission == null) {
7085             return PackageManager.PERMISSION_DENIED;
7086         }
7087         return checkComponentPermission(permission, pid, uid, -1, true);
7088     }
7089
7090     @Override
7091     public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
7092         if (permission == null) {
7093             return PackageManager.PERMISSION_DENIED;
7094         }
7095
7096         // We might be performing an operation on behalf of an indirect binder
7097         // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
7098         // client identity accordingly before proceeding.
7099         Identity tlsIdentity = sCallerIdentity.get();
7100         if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7101             Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
7102                     + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
7103             uid = tlsIdentity.uid;
7104             pid = tlsIdentity.pid;
7105         }
7106
7107         return checkComponentPermission(permission, pid, uid, -1, true);
7108     }
7109
7110     /**
7111      * Binder IPC calls go through the public entry point.
7112      * This can be called with or without the global lock held.
7113      */
7114     int checkCallingPermission(String permission) {
7115         return checkPermission(permission,
7116                 Binder.getCallingPid(),
7117                 UserHandle.getAppId(Binder.getCallingUid()));
7118     }
7119
7120     /**
7121      * This can be called with or without the global lock held.
7122      */
7123     void enforceCallingPermission(String permission, String func) {
7124         if (checkCallingPermission(permission)
7125                 == PackageManager.PERMISSION_GRANTED) {
7126             return;
7127         }
7128
7129         String msg = "Permission Denial: " + func + " from pid="
7130                 + Binder.getCallingPid()
7131                 + ", uid=" + Binder.getCallingUid()
7132                 + " requires " + permission;
7133         Slog.w(TAG, msg);
7134         throw new SecurityException(msg);
7135     }
7136
7137     /**
7138      * Determine if UID is holding permissions required to access {@link Uri} in
7139      * the given {@link ProviderInfo}. Final permission checking is always done
7140      * in {@link ContentProvider}.
7141      */
7142     private final boolean checkHoldingPermissionsLocked(
7143             IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
7144         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7145                 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
7146         if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
7147             if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
7148                     != PERMISSION_GRANTED) {
7149                 return false;
7150             }
7151         }
7152         return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
7153     }
7154
7155     private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
7156             GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
7157         if (pi.applicationInfo.uid == uid) {
7158             return true;
7159         } else if (!pi.exported) {
7160             return false;
7161         }
7162
7163         boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
7164         boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
7165         try {
7166             // check if target holds top-level <provider> permissions
7167             if (!readMet && pi.readPermission != null && considerUidPermissions
7168                     && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
7169                 readMet = true;
7170             }
7171             if (!writeMet && pi.writePermission != null && considerUidPermissions
7172                     && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
7173                 writeMet = true;
7174             }
7175
7176             // track if unprotected read/write is allowed; any denied
7177             // <path-permission> below removes this ability
7178             boolean allowDefaultRead = pi.readPermission == null;
7179             boolean allowDefaultWrite = pi.writePermission == null;
7180
7181             // check if target holds any <path-permission> that match uri
7182             final PathPermission[] pps = pi.pathPermissions;
7183             if (pps != null) {
7184                 final String path = grantUri.uri.getPath();
7185                 int i = pps.length;
7186                 while (i > 0 && (!readMet || !writeMet)) {
7187                     i--;
7188                     PathPermission pp = pps[i];
7189                     if (pp.match(path)) {
7190                         if (!readMet) {
7191                             final String pprperm = pp.getReadPermission();
7192                             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7193                                     "Checking read perm for " + pprperm + " for " + pp.getPath()
7194                                     + ": match=" + pp.match(path)
7195                                     + " check=" + pm.checkUidPermission(pprperm, uid));
7196                             if (pprperm != null) {
7197                                 if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7198                                         == PERMISSION_GRANTED) {
7199                                     readMet = true;
7200                                 } else {
7201                                     allowDefaultRead = false;
7202                                 }
7203                             }
7204                         }
7205                         if (!writeMet) {
7206                             final String ppwperm = pp.getWritePermission();
7207                             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7208                                     "Checking write perm " + ppwperm + " for " + pp.getPath()
7209                                     + ": match=" + pp.match(path)
7210                                     + " check=" + pm.checkUidPermission(ppwperm, uid));
7211                             if (ppwperm != null) {
7212                                 if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7213                                         == PERMISSION_GRANTED) {
7214                                     writeMet = true;
7215                                 } else {
7216                                     allowDefaultWrite = false;
7217                                 }
7218                             }
7219                         }
7220                     }
7221                 }
7222             }
7223
7224             // grant unprotected <provider> read/write, if not blocked by
7225             // <path-permission> above
7226             if (allowDefaultRead) readMet = true;
7227             if (allowDefaultWrite) writeMet = true;
7228
7229         } catch (RemoteException e) {
7230             return false;
7231         }
7232
7233         return readMet && writeMet;
7234     }
7235
7236     private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
7237         ProviderInfo pi = null;
7238         ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7239         if (cpr != null) {
7240             pi = cpr.info;
7241         } else {
7242             try {
7243                 pi = AppGlobals.getPackageManager().resolveContentProvider(
7244                         authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
7245             } catch (RemoteException ex) {
7246             }
7247         }
7248         return pi;
7249     }
7250
7251     private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7252         final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7253         if (targetUris != null) {
7254             return targetUris.get(grantUri);
7255         }
7256         return null;
7257     }
7258
7259     private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7260             String targetPkg, int targetUid, GrantUri grantUri) {
7261         ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7262         if (targetUris == null) {
7263             targetUris = Maps.newArrayMap();
7264             mGrantedUriPermissions.put(targetUid, targetUris);
7265         }
7266
7267         UriPermission perm = targetUris.get(grantUri);
7268         if (perm == null) {
7269             perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7270             targetUris.put(grantUri, perm);
7271         }
7272
7273         return perm;
7274     }
7275
7276     private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7277             final int modeFlags) {
7278         final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7279         final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7280                 : UriPermission.STRENGTH_OWNED;
7281
7282         // Root gets to do everything.
7283         if (uid == 0) {
7284             return true;
7285         }
7286
7287         final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7288         if (perms == null) return false;
7289
7290         // First look for exact match
7291         final UriPermission exactPerm = perms.get(grantUri);
7292         if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7293             return true;
7294         }
7295
7296         // No exact match, look for prefixes
7297         final int N = perms.size();
7298         for (int i = 0; i < N; i++) {
7299             final UriPermission perm = perms.valueAt(i);
7300             if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7301                     && perm.getStrength(modeFlags) >= minStrength) {
7302                 return true;
7303             }
7304         }
7305
7306         return false;
7307     }
7308
7309     /**
7310      * @param uri This uri must NOT contain an embedded userId.
7311      * @param userId The userId in which the uri is to be resolved.
7312      */
7313     @Override
7314     public int checkUriPermission(Uri uri, int pid, int uid,
7315             final int modeFlags, int userId, IBinder callerToken) {
7316         enforceNotIsolatedCaller("checkUriPermission");
7317
7318         // Another redirected-binder-call permissions check as in
7319         // {@link checkPermissionWithToken}.
7320         Identity tlsIdentity = sCallerIdentity.get();
7321         if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7322             uid = tlsIdentity.uid;
7323             pid = tlsIdentity.pid;
7324         }
7325
7326         // Our own process gets to do everything.
7327         if (pid == MY_PID) {
7328             return PackageManager.PERMISSION_GRANTED;
7329         }
7330         synchronized (this) {
7331             return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7332                     ? PackageManager.PERMISSION_GRANTED
7333                     : PackageManager.PERMISSION_DENIED;
7334         }
7335     }
7336
7337     /**
7338      * Check if the targetPkg can be granted permission to access uri by
7339      * the callingUid using the given modeFlags.  Throws a security exception
7340      * if callingUid is not allowed to do this.  Returns the uid of the target
7341      * if the URI permission grant should be performed; returns -1 if it is not
7342      * needed (for example targetPkg already has permission to access the URI).
7343      * If you already know the uid of the target, you can supply it in
7344      * lastTargetUid else set that to -1.
7345      */
7346     int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7347             final int modeFlags, int lastTargetUid) {
7348         if (!Intent.isAccessUriMode(modeFlags)) {
7349             return -1;
7350         }
7351
7352         if (targetPkg != null) {
7353             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7354                     "Checking grant " + targetPkg + " permission to " + grantUri);
7355         }
7356
7357         final IPackageManager pm = AppGlobals.getPackageManager();
7358
7359         // If this is not a content: uri, we can't do anything with it.
7360         if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7361             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7362                     "Can't grant URI permission for non-content URI: " + grantUri);
7363             return -1;
7364         }
7365
7366         final String authority = grantUri.uri.getAuthority();
7367         final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7368         if (pi == null) {
7369             Slog.w(TAG, "No content provider found for permission check: " +
7370                     grantUri.uri.toSafeString());
7371             return -1;
7372         }
7373
7374         int targetUid = lastTargetUid;
7375         if (targetUid < 0 && targetPkg != null) {
7376             try {
7377                 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
7378                 if (targetUid < 0) {
7379                     if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7380                             "Can't grant URI permission no uid for: " + targetPkg);
7381                     return -1;
7382                 }
7383             } catch (RemoteException ex) {
7384                 return -1;
7385             }
7386         }
7387
7388         if (targetUid >= 0) {
7389             // First...  does the target actually need this permission?
7390             if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7391                 // No need to grant the target this permission.
7392                 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7393                         "Target " + targetPkg + " already has full permission to " + grantUri);
7394                 return -1;
7395             }
7396         } else {
7397             // First...  there is no target package, so can anyone access it?
7398             boolean allowed = pi.exported;
7399             if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7400                 if (pi.readPermission != null) {
7401                     allowed = false;
7402                 }
7403             }
7404             if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7405                 if (pi.writePermission != null) {
7406                     allowed = false;
7407                 }
7408             }
7409             if (allowed) {
7410                 return -1;
7411             }
7412         }
7413
7414         /* There is a special cross user grant if:
7415          * - The target is on another user.
7416          * - Apps on the current user can access the uri without any uid permissions.
7417          * In this case, we grant a uri permission, even if the ContentProvider does not normally
7418          * grant uri permissions.
7419          */
7420         boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7421                 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7422                 modeFlags, false /*without considering the uid permissions*/);
7423
7424         // Second...  is the provider allowing granting of URI permissions?
7425         if (!specialCrossUserGrant) {
7426             if (!pi.grantUriPermissions) {
7427                 throw new SecurityException("Provider " + pi.packageName
7428                         + "/" + pi.name
7429                         + " does not allow granting of Uri permissions (uri "
7430                         + grantUri + ")");
7431             }
7432             if (pi.uriPermissionPatterns != null) {
7433                 final int N = pi.uriPermissionPatterns.length;
7434                 boolean allowed = false;
7435                 for (int i=0; i<N; i++) {
7436                     if (pi.uriPermissionPatterns[i] != null
7437                             && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7438                         allowed = true;
7439                         break;
7440                     }
7441                 }
7442                 if (!allowed) {
7443                     throw new SecurityException("Provider " + pi.packageName
7444                             + "/" + pi.name
7445                             + " does not allow granting of permission to path of Uri "
7446                             + grantUri);
7447                 }
7448             }
7449         }
7450
7451         // Third...  does the caller itself have permission to access
7452         // this uri?
7453         if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
7454             if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7455                 // Require they hold a strong enough Uri permission
7456                 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7457                     throw new SecurityException("Uid " + callingUid
7458                             + " does not have permission to uri " + grantUri);
7459                 }
7460             }
7461         }
7462         return targetUid;
7463     }
7464
7465     /**
7466      * @param uri This uri must NOT contain an embedded userId.
7467      * @param userId The userId in which the uri is to be resolved.
7468      */
7469     @Override
7470     public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
7471             final int modeFlags, int userId) {
7472         enforceNotIsolatedCaller("checkGrantUriPermission");
7473         synchronized(this) {
7474             return checkGrantUriPermissionLocked(callingUid, targetPkg,
7475                     new GrantUri(userId, uri, false), modeFlags, -1);
7476         }
7477     }
7478
7479     void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
7480             final int modeFlags, UriPermissionOwner owner) {
7481         if (!Intent.isAccessUriMode(modeFlags)) {
7482             return;
7483         }
7484
7485         // So here we are: the caller has the assumed permission
7486         // to the uri, and the target doesn't.  Let's now give this to
7487         // the target.
7488
7489         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7490                 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
7491
7492         final String authority = grantUri.uri.getAuthority();
7493         final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7494         if (pi == null) {
7495             Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
7496             return;
7497         }
7498
7499         if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
7500             grantUri.prefix = true;
7501         }
7502         final UriPermission perm = findOrCreateUriPermissionLocked(
7503                 pi.packageName, targetPkg, targetUid, grantUri);
7504         perm.grantModes(modeFlags, owner);
7505     }
7506
7507     void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7508             final int modeFlags, UriPermissionOwner owner, int targetUserId) {
7509         if (targetPkg == null) {
7510             throw new NullPointerException("targetPkg");
7511         }
7512         int targetUid;
7513         final IPackageManager pm = AppGlobals.getPackageManager();
7514         try {
7515             targetUid = pm.getPackageUid(targetPkg, targetUserId);
7516         } catch (RemoteException ex) {
7517             return;
7518         }
7519
7520         targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
7521                 targetUid);
7522         if (targetUid < 0) {
7523             return;
7524         }
7525
7526         grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
7527                 owner);
7528     }
7529
7530     static class NeededUriGrants extends ArrayList<GrantUri> {
7531         final String targetPkg;
7532         final int targetUid;
7533         final int flags;
7534
7535         NeededUriGrants(String targetPkg, int targetUid, int flags) {
7536             this.targetPkg = targetPkg;
7537             this.targetUid = targetUid;
7538             this.flags = flags;
7539         }
7540     }
7541
7542     /**
7543      * Like checkGrantUriPermissionLocked, but takes an Intent.
7544      */
7545     NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
7546             String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
7547         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7548                 "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
7549                 + " clip=" + (intent != null ? intent.getClipData() : null)
7550                 + " from " + intent + "; flags=0x"
7551                 + Integer.toHexString(intent != null ? intent.getFlags() : 0));
7552
7553         if (targetPkg == null) {
7554             throw new NullPointerException("targetPkg");
7555         }
7556
7557         if (intent == null) {
7558             return null;
7559         }
7560         Uri data = intent.getData();
7561         ClipData clip = intent.getClipData();
7562         if (data == null && clip == null) {
7563             return null;
7564         }
7565         // Default userId for uris in the intent (if they don't specify it themselves)
7566         int contentUserHint = intent.getContentUserHint();
7567         if (contentUserHint == UserHandle.USER_CURRENT) {
7568             contentUserHint = UserHandle.getUserId(callingUid);
7569         }
7570         final IPackageManager pm = AppGlobals.getPackageManager();
7571         int targetUid;
7572         if (needed != null) {
7573             targetUid = needed.targetUid;
7574         } else {
7575             try {
7576                 targetUid = pm.getPackageUid(targetPkg, targetUserId);
7577             } catch (RemoteException ex) {
7578                 return null;
7579             }
7580             if (targetUid < 0) {
7581                 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7582                         "Can't grant URI permission no uid for: " + targetPkg
7583                         + " on user " + targetUserId);
7584                 return null;
7585             }
7586         }
7587         if (data != null) {
7588             GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
7589             targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7590                     targetUid);
7591             if (targetUid > 0) {
7592                 if (needed == null) {
7593                     needed = new NeededUriGrants(targetPkg, targetUid, mode);
7594                 }
7595                 needed.add(grantUri);
7596             }
7597         }
7598         if (clip != null) {
7599             for (int i=0; i<clip.getItemCount(); i++) {
7600                 Uri uri = clip.getItemAt(i).getUri();
7601                 if (uri != null) {
7602                     GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
7603                     targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7604                             targetUid);
7605                     if (targetUid > 0) {
7606                         if (needed == null) {
7607                             needed = new NeededUriGrants(targetPkg, targetUid, mode);
7608                         }
7609                         needed.add(grantUri);
7610                     }
7611                 } else {
7612                     Intent clipIntent = clip.getItemAt(i).getIntent();
7613                     if (clipIntent != null) {
7614                         NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
7615                                 callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
7616                         if (newNeeded != null) {
7617                             needed = newNeeded;
7618                         }
7619                     }
7620                 }
7621             }
7622         }
7623
7624         return needed;
7625     }
7626
7627     /**
7628      * Like grantUriPermissionUncheckedLocked, but takes an Intent.
7629      */
7630     void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
7631             UriPermissionOwner owner) {
7632         if (needed != null) {
7633             for (int i=0; i<needed.size(); i++) {
7634                 GrantUri grantUri = needed.get(i);
7635                 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
7636                         grantUri, needed.flags, owner);
7637             }
7638         }
7639     }
7640
7641     void grantUriPermissionFromIntentLocked(int callingUid,
7642             String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
7643         NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
7644                 intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
7645         if (needed == null) {
7646             return;
7647         }
7648
7649         grantUriPermissionUncheckedFromIntentLocked(needed, owner);
7650     }
7651
7652     /**
7653      * @param uri This uri must NOT contain an embedded userId.
7654      * @param userId The userId in which the uri is to be resolved.
7655      */
7656     @Override
7657     public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
7658             final int modeFlags, int userId) {
7659         enforceNotIsolatedCaller("grantUriPermission");
7660         GrantUri grantUri = new GrantUri(userId, uri, false);
7661         synchronized(this) {
7662             final ProcessRecord r = getRecordForAppLocked(caller);
7663             if (r == null) {
7664                 throw new SecurityException("Unable to find app for caller "
7665                         + caller
7666                         + " when granting permission to uri " + grantUri);
7667             }
7668             if (targetPkg == null) {
7669                 throw new IllegalArgumentException("null target");
7670             }
7671             if (grantUri == null) {
7672                 throw new IllegalArgumentException("null uri");
7673             }
7674
7675             Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
7676                     | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
7677                     | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
7678                     | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
7679
7680             grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
7681                     UserHandle.getUserId(r.uid));
7682         }
7683     }
7684
7685     void removeUriPermissionIfNeededLocked(UriPermission perm) {
7686         if (perm.modeFlags == 0) {
7687             final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7688                     perm.targetUid);
7689             if (perms != null) {
7690                 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7691                         "Removing " + perm.targetUid + " permission to " + perm.uri);
7692
7693                 perms.remove(perm.uri);
7694                 if (perms.isEmpty()) {
7695                     mGrantedUriPermissions.remove(perm.targetUid);
7696                 }
7697             }
7698         }
7699     }
7700
7701     private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
7702         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7703                 "Revoking all granted permissions to " + grantUri);
7704
7705         final IPackageManager pm = AppGlobals.getPackageManager();
7706         final String authority = grantUri.uri.getAuthority();
7707         final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7708         if (pi == null) {
7709             Slog.w(TAG, "No content provider found for permission revoke: "
7710                     + grantUri.toSafeString());
7711             return;
7712         }
7713
7714         // Does the caller have this permission on the URI?
7715         if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7716             // If they don't have direct access to the URI, then revoke any
7717             // ownerless URI permissions that have been granted to them.
7718             final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7719             if (perms != null) {
7720                 boolean persistChanged = false;
7721                 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7722                     final UriPermission perm = it.next();
7723                     if (perm.uri.sourceUserId == grantUri.sourceUserId
7724                             && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7725                         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7726                                 "Revoking non-owned " + perm.targetUid
7727                                 + " permission to " + perm.uri);
7728                         persistChanged |= perm.revokeModes(
7729                                 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
7730                         if (perm.modeFlags == 0) {
7731                             it.remove();
7732                         }
7733                     }
7734                 }
7735                 if (perms.isEmpty()) {
7736                     mGrantedUriPermissions.remove(callingUid);
7737                 }
7738                 if (persistChanged) {
7739                     schedulePersistUriGrants();
7740                 }
7741             }
7742             return;
7743         }
7744
7745         boolean persistChanged = false;
7746
7747         // Go through all of the permissions and remove any that match.
7748         int N = mGrantedUriPermissions.size();
7749         for (int i = 0; i < N; i++) {
7750             final int targetUid = mGrantedUriPermissions.keyAt(i);
7751             final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7752
7753             for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7754                 final UriPermission perm = it.next();
7755                 if (perm.uri.sourceUserId == grantUri.sourceUserId
7756                         && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7757                     if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7758                                 "Revoking " + perm.targetUid + " permission to " + perm.uri);
7759                     persistChanged |= perm.revokeModes(
7760                             modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7761                     if (perm.modeFlags == 0) {
7762                         it.remove();
7763                     }
7764                 }
7765             }
7766
7767             if (perms.isEmpty()) {
7768                 mGrantedUriPermissions.remove(targetUid);
7769                 N--;
7770                 i--;
7771             }
7772         }
7773
7774         if (persistChanged) {
7775             schedulePersistUriGrants();
7776         }
7777     }
7778
7779     /**
7780      * @param uri This uri must NOT contain an embedded userId.
7781      * @param userId The userId in which the uri is to be resolved.
7782      */
7783     @Override
7784     public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
7785             int userId) {
7786         enforceNotIsolatedCaller("revokeUriPermission");
7787         synchronized(this) {
7788             final ProcessRecord r = getRecordForAppLocked(caller);
7789             if (r == null) {
7790                 throw new SecurityException("Unable to find app for caller "
7791                         + caller
7792                         + " when revoking permission to uri " + uri);
7793             }
7794             if (uri == null) {
7795                 Slog.w(TAG, "revokeUriPermission: null uri");
7796                 return;
7797             }
7798
7799             if (!Intent.isAccessUriMode(modeFlags)) {
7800                 return;
7801             }
7802
7803             final String authority = uri.getAuthority();
7804             final ProviderInfo pi = getProviderInfoLocked(authority, userId);
7805             if (pi == null) {
7806                 Slog.w(TAG, "No content provider found for permission revoke: "
7807                         + uri.toSafeString());
7808                 return;
7809             }
7810
7811             revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
7812         }
7813     }
7814
7815     /**
7816      * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
7817      * given package.
7818      *
7819      * @param packageName Package name to match, or {@code null} to apply to all
7820      *            packages.
7821      * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
7822      *            to all users.
7823      * @param persistable If persistable grants should be removed.
7824      */
7825     private void removeUriPermissionsForPackageLocked(
7826             String packageName, int userHandle, boolean persistable) {
7827         if (userHandle == UserHandle.USER_ALL && packageName == null) {
7828             throw new IllegalArgumentException("Must narrow by either package or user");
7829         }
7830
7831         boolean persistChanged = false;
7832
7833         int N = mGrantedUriPermissions.size();
7834         for (int i = 0; i < N; i++) {
7835             final int targetUid = mGrantedUriPermissions.keyAt(i);
7836             final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7837
7838             // Only inspect grants matching user
7839             if (userHandle == UserHandle.USER_ALL
7840                     || userHandle == UserHandle.getUserId(targetUid)) {
7841                 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7842                     final UriPermission perm = it.next();
7843
7844                     // Only inspect grants matching package
7845                     if (packageName == null || perm.sourcePkg.equals(packageName)
7846                             || perm.targetPkg.equals(packageName)) {
7847                         persistChanged |= perm.revokeModes(persistable
7848                                 ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7849
7850                         // Only remove when no modes remain; any persisted grants
7851                         // will keep this alive.
7852                         if (perm.modeFlags == 0) {
7853                             it.remove();
7854                         }
7855                     }
7856                 }
7857
7858                 if (perms.isEmpty()) {
7859                     mGrantedUriPermissions.remove(targetUid);
7860                     N--;
7861                     i--;
7862                 }
7863             }
7864         }
7865
7866         if (persistChanged) {
7867             schedulePersistUriGrants();
7868         }
7869     }
7870
7871     @Override
7872     public IBinder newUriPermissionOwner(String name) {
7873         enforceNotIsolatedCaller("newUriPermissionOwner");
7874         synchronized(this) {
7875             UriPermissionOwner owner = new UriPermissionOwner(this, name);
7876             return owner.getExternalTokenLocked();
7877         }
7878     }
7879
7880     /**
7881      * @param uri This uri must NOT contain an embedded userId.
7882      * @param sourceUserId The userId in which the uri is to be resolved.
7883      * @param targetUserId The userId of the app that receives the grant.
7884      */
7885     @Override
7886     public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
7887             final int modeFlags, int sourceUserId, int targetUserId) {
7888         targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
7889                 targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null);
7890         synchronized(this) {
7891             UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7892             if (owner == null) {
7893                 throw new IllegalArgumentException("Unknown owner: " + token);
7894             }
7895             if (fromUid != Binder.getCallingUid()) {
7896                 if (Binder.getCallingUid() != Process.myUid()) {
7897                     // Only system code can grant URI permissions on behalf
7898                     // of other users.
7899                     throw new SecurityException("nice try");
7900                 }
7901             }
7902             if (targetPkg == null) {
7903                 throw new IllegalArgumentException("null target");
7904             }
7905             if (uri == null) {
7906                 throw new IllegalArgumentException("null uri");
7907             }
7908
7909             grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
7910                     modeFlags, owner, targetUserId);
7911         }
7912     }
7913
7914     /**
7915      * @param uri This uri must NOT contain an embedded userId.
7916      * @param userId The userId in which the uri is to be resolved.
7917      */
7918     @Override
7919     public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
7920         synchronized(this) {
7921             UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7922             if (owner == null) {
7923                 throw new IllegalArgumentException("Unknown owner: " + token);
7924             }
7925
7926             if (uri == null) {
7927                 owner.removeUriPermissionsLocked(mode);
7928             } else {
7929                 owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
7930             }
7931         }
7932     }
7933
7934     private void schedulePersistUriGrants() {
7935         if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
7936             mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
7937                     10 * DateUtils.SECOND_IN_MILLIS);
7938         }
7939     }
7940
7941     private void writeGrantedUriPermissions() {
7942         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
7943
7944         // Snapshot permissions so we can persist without lock
7945         ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
7946         synchronized (this) {
7947             final int size = mGrantedUriPermissions.size();
7948             for (int i = 0; i < size; i++) {
7949                 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7950                 for (UriPermission perm : perms.values()) {
7951                     if (perm.persistedModeFlags != 0) {
7952                         persist.add(perm.snapshot());
7953                     }
7954                 }
7955             }
7956         }
7957
7958         FileOutputStream fos = null;
7959         try {
7960             fos = mGrantFile.startWrite();
7961
7962             XmlSerializer out = new FastXmlSerializer();
7963             out.setOutput(fos, StandardCharsets.UTF_8.name());
7964             out.startDocument(null, true);
7965             out.startTag(null, TAG_URI_GRANTS);
7966             for (UriPermission.Snapshot perm : persist) {
7967                 out.startTag(null, TAG_URI_GRANT);
7968                 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
7969                 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
7970                 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
7971                 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
7972                 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
7973                 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
7974                 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
7975                 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
7976                 out.endTag(null, TAG_URI_GRANT);
7977             }
7978             out.endTag(null, TAG_URI_GRANTS);
7979             out.endDocument();
7980
7981             mGrantFile.finishWrite(fos);
7982         } catch (IOException e) {
7983             if (fos != null) {
7984                 mGrantFile.failWrite(fos);
7985             }
7986         }
7987     }
7988
7989     private void readGrantedUriPermissionsLocked() {
7990         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
7991
7992         final long now = System.currentTimeMillis();
7993
7994         FileInputStream fis = null;
7995         try {
7996             fis = mGrantFile.openRead();
7997             final XmlPullParser in = Xml.newPullParser();
7998             in.setInput(fis, StandardCharsets.UTF_8.name());
7999
8000             int type;
8001             while ((type = in.next()) != END_DOCUMENT) {
8002                 final String tag = in.getName();
8003                 if (type == START_TAG) {
8004                     if (TAG_URI_GRANT.equals(tag)) {
8005                         final int sourceUserId;
8006                         final int targetUserId;
8007                         final int userHandle = readIntAttribute(in,
8008                                 ATTR_USER_HANDLE, UserHandle.USER_NULL);
8009                         if (userHandle != UserHandle.USER_NULL) {
8010                             // For backwards compatibility.
8011                             sourceUserId = userHandle;
8012                             targetUserId = userHandle;
8013                         } else {
8014                             sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
8015                             targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
8016                         }
8017                         final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
8018                         final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
8019                         final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
8020                         final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
8021                         final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
8022                         final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
8023
8024                         // Sanity check that provider still belongs to source package
8025                         final ProviderInfo pi = getProviderInfoLocked(
8026                                 uri.getAuthority(), sourceUserId);
8027                         if (pi != null && sourcePkg.equals(pi.packageName)) {
8028                             int targetUid = -1;
8029                             try {
8030                                 targetUid = AppGlobals.getPackageManager()
8031                                         .getPackageUid(targetPkg, targetUserId);
8032                             } catch (RemoteException e) {
8033                             }
8034                             if (targetUid != -1) {
8035                                 final UriPermission perm = findOrCreateUriPermissionLocked(
8036                                         sourcePkg, targetPkg, targetUid,
8037                                         new GrantUri(sourceUserId, uri, prefix));
8038                                 perm.initPersistedModes(modeFlags, createdTime);
8039                             }
8040                         } else {
8041                             Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
8042                                     + " but instead found " + pi);
8043                         }
8044                     }
8045                 }
8046             }
8047         } catch (FileNotFoundException e) {
8048             // Missing grants is okay
8049         } catch (IOException e) {
8050             Slog.wtf(TAG, "Failed reading Uri grants", e);
8051         } catch (XmlPullParserException e) {
8052             Slog.wtf(TAG, "Failed reading Uri grants", e);
8053         } finally {
8054             IoUtils.closeQuietly(fis);
8055         }
8056     }
8057
8058     /**
8059      * @param uri This uri must NOT contain an embedded userId.
8060      * @param userId The userId in which the uri is to be resolved.
8061      */
8062     @Override
8063     public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8064         enforceNotIsolatedCaller("takePersistableUriPermission");
8065
8066         Preconditions.checkFlagsArgument(modeFlags,
8067                 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8068
8069         synchronized (this) {
8070             final int callingUid = Binder.getCallingUid();
8071             boolean persistChanged = false;
8072             GrantUri grantUri = new GrantUri(userId, uri, false);
8073
8074             UriPermission exactPerm = findUriPermissionLocked(callingUid,
8075                     new GrantUri(userId, uri, false));
8076             UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8077                     new GrantUri(userId, uri, true));
8078
8079             final boolean exactValid = (exactPerm != null)
8080                     && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
8081             final boolean prefixValid = (prefixPerm != null)
8082                     && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
8083
8084             if (!(exactValid || prefixValid)) {
8085                 throw new SecurityException("No persistable permission grants found for UID "
8086                         + callingUid + " and Uri " + grantUri.toSafeString());
8087             }
8088
8089             if (exactValid) {
8090                 persistChanged |= exactPerm.takePersistableModes(modeFlags);
8091             }
8092             if (prefixValid) {
8093                 persistChanged |= prefixPerm.takePersistableModes(modeFlags);
8094             }
8095
8096             persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
8097
8098             if (persistChanged) {
8099                 schedulePersistUriGrants();
8100             }
8101         }
8102     }
8103
8104     /**
8105      * @param uri This uri must NOT contain an embedded userId.
8106      * @param userId The userId in which the uri is to be resolved.
8107      */
8108     @Override
8109     public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8110         enforceNotIsolatedCaller("releasePersistableUriPermission");
8111
8112         Preconditions.checkFlagsArgument(modeFlags,
8113                 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8114
8115         synchronized (this) {
8116             final int callingUid = Binder.getCallingUid();
8117             boolean persistChanged = false;
8118
8119             UriPermission exactPerm = findUriPermissionLocked(callingUid,
8120                     new GrantUri(userId, uri, false));
8121             UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8122                     new GrantUri(userId, uri, true));
8123             if (exactPerm == null && prefixPerm == null) {
8124                 throw new SecurityException("No permission grants found for UID " + callingUid
8125                         + " and Uri " + uri.toSafeString());
8126             }
8127
8128             if (exactPerm != null) {
8129                 persistChanged |= exactPerm.releasePersistableModes(modeFlags);
8130                 removeUriPermissionIfNeededLocked(exactPerm);
8131             }
8132             if (prefixPerm != null) {
8133                 persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
8134                 removeUriPermissionIfNeededLocked(prefixPerm);
8135             }
8136
8137             if (persistChanged) {
8138                 schedulePersistUriGrants();
8139             }
8140         }
8141     }
8142
8143     /**
8144      * Prune any older {@link UriPermission} for the given UID until outstanding
8145      * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
8146      *
8147      * @return if any mutations occured that require persisting.
8148      */
8149     private boolean maybePrunePersistedUriGrantsLocked(int uid) {
8150         final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8151         if (perms == null) return false;
8152         if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
8153
8154         final ArrayList<UriPermission> persisted = Lists.newArrayList();
8155         for (UriPermission perm : perms.values()) {
8156             if (perm.persistedModeFlags != 0) {
8157                 persisted.add(perm);
8158             }
8159         }
8160
8161         final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
8162         if (trimCount <= 0) return false;
8163
8164         Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
8165         for (int i = 0; i < trimCount; i++) {
8166             final UriPermission perm = persisted.get(i);
8167
8168             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8169                     "Trimming grant created at " + perm.persistedCreateTime);
8170
8171             perm.releasePersistableModes(~0);
8172             removeUriPermissionIfNeededLocked(perm);
8173         }
8174
8175         return true;
8176     }
8177
8178     @Override
8179     public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8180             String packageName, boolean incoming) {
8181         enforceNotIsolatedCaller("getPersistedUriPermissions");
8182         Preconditions.checkNotNull(packageName, "packageName");
8183
8184         final int callingUid = Binder.getCallingUid();
8185         final IPackageManager pm = AppGlobals.getPackageManager();
8186         try {
8187             final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
8188             if (packageUid != callingUid) {
8189                 throw new SecurityException(
8190                         "Package " + packageName + " does not belong to calling UID " + callingUid);
8191             }
8192         } catch (RemoteException e) {
8193             throw new SecurityException("Failed to verify package name ownership");
8194         }
8195
8196         final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8197         synchronized (this) {
8198             if (incoming) {
8199                 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8200                         callingUid);
8201                 if (perms == null) {
8202                     Slog.w(TAG, "No permission grants found for " + packageName);
8203                 } else {
8204                     for (UriPermission perm : perms.values()) {
8205                         if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8206                             result.add(perm.buildPersistedPublicApiObject());
8207                         }
8208                     }
8209                 }
8210             } else {
8211                 final int size = mGrantedUriPermissions.size();
8212                 for (int i = 0; i < size; i++) {
8213                     final ArrayMap<GrantUri, UriPermission> perms =
8214                             mGrantedUriPermissions.valueAt(i);
8215                     for (UriPermission perm : perms.values()) {
8216                         if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8217                             result.add(perm.buildPersistedPublicApiObject());
8218                         }
8219                     }
8220                 }
8221             }
8222         }
8223         return new ParceledListSlice<android.content.UriPermission>(result);
8224     }
8225
8226     @Override
8227     public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
8228         synchronized (this) {
8229             ProcessRecord app =
8230                 who != null ? getRecordForAppLocked(who) : null;
8231             if (app == null) return;
8232
8233             Message msg = Message.obtain();
8234             msg.what = WAIT_FOR_DEBUGGER_MSG;
8235             msg.obj = app;
8236             msg.arg1 = waiting ? 1 : 0;
8237             mUiHandler.sendMessage(msg);
8238         }
8239     }
8240
8241     @Override
8242     public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
8243         final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
8244         final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
8245         outInfo.availMem = Process.getFreeMemory();
8246         outInfo.totalMem = Process.getTotalMemory();
8247         outInfo.threshold = homeAppMem;
8248         outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
8249         outInfo.hiddenAppThreshold = cachedAppMem;
8250         outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
8251                 ProcessList.SERVICE_ADJ);
8252         outInfo.visibleAppThreshold = mProcessList.getMemLevel(
8253                 ProcessList.VISIBLE_APP_ADJ);
8254         outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
8255                 ProcessList.FOREGROUND_APP_ADJ);
8256     }
8257
8258     // =========================================================
8259     // TASK MANAGEMENT
8260     // =========================================================
8261
8262     @Override
8263     public List<IAppTask> getAppTasks(String callingPackage) {
8264         int callingUid = Binder.getCallingUid();
8265         long ident = Binder.clearCallingIdentity();
8266
8267         synchronized(this) {
8268             ArrayList<IAppTask> list = new ArrayList<IAppTask>();
8269             try {
8270                 if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
8271
8272                 final int N = mRecentTasks.size();
8273                 for (int i = 0; i < N; i++) {
8274                     TaskRecord tr = mRecentTasks.get(i);
8275                     // Skip tasks that do not match the caller.  We don't need to verify
8276                     // callingPackage, because we are also limiting to callingUid and know
8277                     // that will limit to the correct security sandbox.
8278                     if (tr.effectiveUid != callingUid) {
8279                         continue;
8280                     }
8281                     Intent intent = tr.getBaseIntent();
8282                     if (intent == null ||
8283                             !callingPackage.equals(intent.getComponent().getPackageName())) {
8284                         continue;
8285                     }
8286                     ActivityManager.RecentTaskInfo taskInfo =
8287                             createRecentTaskInfoFromTaskRecord(tr);
8288                     AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8289                     list.add(taskImpl);
8290                 }
8291             } finally {
8292                 Binder.restoreCallingIdentity(ident);
8293             }
8294             return list;
8295         }
8296     }
8297
8298     @Override
8299     public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8300         final int callingUid = Binder.getCallingUid();
8301         ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8302
8303         synchronized(this) {
8304             if (DEBUG_ALL) Slog.v(
8305                 TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8306
8307             final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
8308                     callingUid);
8309
8310             // TODO: Improve with MRU list from all ActivityStacks.
8311             mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8312         }
8313
8314         return list;
8315     }
8316
8317     /**
8318      * Creates a new RecentTaskInfo from a TaskRecord.
8319      */
8320     private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8321         // Update the task description to reflect any changes in the task stack
8322         tr.updateTaskDescription();
8323
8324         // Compose the recent task info
8325         ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8326         rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
8327         rti.persistentId = tr.taskId;
8328         rti.baseIntent = new Intent(tr.getBaseIntent());
8329         rti.origActivity = tr.origActivity;
8330         rti.description = tr.lastDescription;
8331         rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8332         rti.userId = tr.userId;
8333         rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8334         rti.firstActiveTime = tr.firstActiveTime;
8335         rti.lastActiveTime = tr.lastActiveTime;
8336         rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8337         rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8338         rti.numActivities = 0;
8339
8340         ActivityRecord base = null;
8341         ActivityRecord top = null;
8342         ActivityRecord tmp;
8343
8344         for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
8345             tmp = tr.mActivities.get(i);
8346             if (tmp.finishing) {
8347                 continue;
8348             }
8349             base = tmp;
8350             if (top == null || (top.state == ActivityState.INITIALIZING)) {
8351                 top = base;
8352             }
8353             rti.numActivities++;
8354         }
8355
8356         rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
8357         rti.topActivity = (top != null) ? top.intent.getComponent() : null;
8358
8359         return rti;
8360     }
8361
8362     private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
8363         boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
8364                 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
8365         if (!allowed) {
8366             if (checkPermission(android.Manifest.permission.GET_TASKS,
8367                     callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
8368                 // Temporary compatibility: some existing apps on the system image may
8369                 // still be requesting the old permission and not switched to the new
8370                 // one; if so, we'll still allow them full access.  This means we need
8371                 // to see if they are holding the old permission and are a system app.
8372                 try {
8373                     if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
8374                         allowed = true;
8375                         if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
8376                                 + " is using old GET_TASKS but privileged; allowing");
8377                     }
8378                 } catch (RemoteException e) {
8379                 }
8380             }
8381         }
8382         if (!allowed) {
8383             if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
8384                     + " does not hold REAL_GET_TASKS; limiting output");
8385         }
8386         return allowed;
8387     }
8388
8389     @Override
8390     public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8391         final int callingUid = Binder.getCallingUid();
8392         userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8393                 false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8394
8395         final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8396         final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8397         synchronized (this) {
8398             final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
8399                     callingUid);
8400             final boolean detailed = checkCallingPermission(
8401                     android.Manifest.permission.GET_DETAILED_TASKS)
8402                     == PackageManager.PERMISSION_GRANTED;
8403
8404             final int recentsCount = mRecentTasks.size();
8405             ArrayList<ActivityManager.RecentTaskInfo> res =
8406                     new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
8407
8408             final Set<Integer> includedUsers;
8409             if (includeProfiles) {
8410                 includedUsers = getProfileIdsLocked(userId);
8411             } else {
8412                 includedUsers = new HashSet<>();
8413             }
8414             includedUsers.add(Integer.valueOf(userId));
8415
8416             for (int i = 0; i < recentsCount && maxNum > 0; i++) {
8417                 TaskRecord tr = mRecentTasks.get(i);
8418                 // Only add calling user or related users recent tasks
8419                 if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
8420                     if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
8421                     continue;
8422                 }
8423
8424                 // Return the entry if desired by the caller.  We always return
8425                 // the first entry, because callers always expect this to be the
8426                 // foreground app.  We may filter others if the caller has
8427                 // not supplied RECENT_WITH_EXCLUDED and there is some reason
8428                 // we should exclude the entry.
8429
8430                 if (i == 0
8431                         || withExcluded
8432                         || (tr.intent == null)
8433                         || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
8434                                 == 0)) {
8435                     if (!allowed) {
8436                         // If the caller doesn't have the GET_TASKS permission, then only
8437                         // allow them to see a small subset of tasks -- their own and home.
8438                         if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
8439                             if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
8440                             continue;
8441                         }
8442                     }
8443                     if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
8444                         if (tr.stack != null && tr.stack.isHomeStack()) {
8445                             if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8446                                     "Skipping, home stack task: " + tr);
8447                             continue;
8448                         }
8449                     }
8450                     if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
8451                         // Don't include auto remove tasks that are finished or finishing.
8452                         if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8453                                 "Skipping, auto-remove without activity: " + tr);
8454                         continue;
8455                     }
8456                     if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
8457                             && !tr.isAvailable) {
8458                         if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8459                                 "Skipping, unavail real act: " + tr);
8460                         continue;
8461                     }
8462
8463                     ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
8464                     if (!detailed) {
8465                         rti.baseIntent.replaceExtras((Bundle)null);
8466                     }
8467
8468                     res.add(rti);
8469                     maxNum--;
8470                 }
8471             }
8472             return res;
8473         }
8474     }
8475
8476     @Override
8477     public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
8478         synchronized (this) {
8479             enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
8480                     "getTaskThumbnail()");
8481             TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(id, false);
8482             if (tr != null) {
8483                 return tr.getTaskThumbnailLocked();
8484             }
8485         }
8486         return null;
8487     }
8488
8489     @Override
8490     public int addAppTask(IBinder activityToken, Intent intent,
8491             ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
8492         final int callingUid = Binder.getCallingUid();
8493         final long callingIdent = Binder.clearCallingIdentity();
8494
8495         try {
8496             synchronized (this) {
8497                 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8498                 if (r == null) {
8499                     throw new IllegalArgumentException("Activity does not exist; token="
8500                             + activityToken);
8501                 }
8502                 ComponentName comp = intent.getComponent();
8503                 if (comp == null) {
8504                     throw new IllegalArgumentException("Intent " + intent
8505                             + " must specify explicit component");
8506                 }
8507                 if (thumbnail.getWidth() != mThumbnailWidth
8508                         || thumbnail.getHeight() != mThumbnailHeight) {
8509                     throw new IllegalArgumentException("Bad thumbnail size: got "
8510                             + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
8511                             + mThumbnailWidth + "x" + mThumbnailHeight);
8512                 }
8513                 if (intent.getSelector() != null) {
8514                     intent.setSelector(null);
8515                 }
8516                 if (intent.getSourceBounds() != null) {
8517                     intent.setSourceBounds(null);
8518                 }
8519                 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
8520                     if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
8521                         // The caller has added this as an auto-remove task...  that makes no
8522                         // sense, so turn off auto-remove.
8523                         intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
8524                     }
8525                 } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
8526                     // Must be a new task.
8527                     intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8528                 }
8529                 if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
8530                     mLastAddedTaskActivity = null;
8531                 }
8532                 ActivityInfo ainfo = mLastAddedTaskActivity;
8533                 if (ainfo == null) {
8534                     ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
8535                             comp, 0, UserHandle.getUserId(callingUid));
8536                     if (ainfo.applicationInfo.uid != callingUid) {
8537                         throw new SecurityException(
8538                                 "Can't add task for another application: target uid="
8539                                 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
8540                     }
8541                 }
8542
8543                 TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo,
8544                         intent, description);
8545
8546                 int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
8547                 if (trimIdx >= 0) {
8548                     // If this would have caused a trim, then we'll abort because that
8549                     // means it would be added at the end of the list but then just removed.
8550                     return INVALID_TASK_ID;
8551                 }
8552
8553                 final int N = mRecentTasks.size();
8554                 if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
8555                     final TaskRecord tr = mRecentTasks.remove(N - 1);
8556                     tr.removedFromRecents();
8557                 }
8558
8559                 task.inRecents = true;
8560                 mRecentTasks.add(task);
8561                 r.task.stack.addTask(task, false, false);
8562
8563                 task.setLastThumbnail(thumbnail);
8564                 task.freeLastThumbnail();
8565
8566                 return task.taskId;
8567             }
8568         } finally {
8569             Binder.restoreCallingIdentity(callingIdent);
8570         }
8571     }
8572
8573     @Override
8574     public Point getAppTaskThumbnailSize() {
8575         synchronized (this) {
8576             return new Point(mThumbnailWidth,  mThumbnailHeight);
8577         }
8578     }
8579
8580     @Override
8581     public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
8582         synchronized (this) {
8583             ActivityRecord r = ActivityRecord.isInStackLocked(token);
8584             if (r != null) {
8585                 r.setTaskDescription(td);
8586                 r.task.updateTaskDescription();
8587             }
8588         }
8589     }
8590
8591     @Override
8592     public void setTaskResizeable(int taskId, boolean resizeable) {
8593         synchronized (this) {
8594             TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId, false);
8595             if (task == null) {
8596                 Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
8597                 return;
8598             }
8599             if (task.mResizeable != resizeable) {
8600                 task.mResizeable = resizeable;
8601                 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
8602                 mStackSupervisor.resumeTopActivitiesLocked();
8603             }
8604         }
8605     }
8606
8607     @Override
8608     public void resizeTask(int taskId, Rect bounds) {
8609         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8610                 "resizeTask()");
8611         long ident = Binder.clearCallingIdentity();
8612         try {
8613             synchronized (this) {
8614                 TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8615                 if (task == null) {
8616                     Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
8617                     return;
8618                 }
8619                 mStackSupervisor.resizeTaskLocked(task, bounds);
8620             }
8621         } finally {
8622             Binder.restoreCallingIdentity(ident);
8623         }
8624     }
8625
8626     @Override
8627     public Bitmap getTaskDescriptionIcon(String filename) {
8628         if (!FileUtils.isValidExtFilename(filename)
8629                 || !filename.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
8630             throw new IllegalArgumentException("Bad filename: " + filename);
8631         }
8632         return mTaskPersister.getTaskDescriptionIcon(filename);
8633     }
8634
8635     @Override
8636     public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
8637             throws RemoteException {
8638         if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
8639                 opts.getCustomInPlaceResId() == 0) {
8640             throw new IllegalArgumentException("Expected in-place ActivityOption " +
8641                     "with valid animation");
8642         }
8643         mWindowManager.prepareAppTransition(AppTransition.TRANSIT_TASK_IN_PLACE, false);
8644         mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
8645                 opts.getCustomInPlaceResId());
8646         mWindowManager.executeAppTransition();
8647     }
8648
8649     private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess) {
8650         mRecentTasks.remove(tr);
8651         tr.removedFromRecents();
8652         ComponentName component = tr.getBaseIntent().getComponent();
8653         if (component == null) {
8654             Slog.w(TAG, "No component for base intent of task: " + tr);
8655             return;
8656         }
8657
8658         // Find any running services associated with this app and stop if needed.
8659         mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
8660
8661         if (!killProcess) {
8662             return;
8663         }
8664
8665         // Determine if the process(es) for this task should be killed.
8666         final String pkg = component.getPackageName();
8667         ArrayList<ProcessRecord> procsToKill = new ArrayList<>();
8668         ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
8669         for (int i = 0; i < pmap.size(); i++) {
8670
8671             SparseArray<ProcessRecord> uids = pmap.valueAt(i);
8672             for (int j = 0; j < uids.size(); j++) {
8673                 ProcessRecord proc = uids.valueAt(j);
8674                 if (proc.userId != tr.userId) {
8675                     // Don't kill process for a different user.
8676                     continue;
8677                 }
8678                 if (proc == mHomeProcess) {
8679                     // Don't kill the home process along with tasks from the same package.
8680                     continue;
8681                 }
8682                 if (!proc.pkgList.containsKey(pkg)) {
8683                     // Don't kill process that is not associated with this task.
8684                     continue;
8685                 }
8686
8687                 for (int k = 0; k < proc.activities.size(); k++) {
8688                     TaskRecord otherTask = proc.activities.get(k).task;
8689                     if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
8690                         // Don't kill process(es) that has an activity in a different task that is
8691                         // also in recents.
8692                         return;
8693                     }
8694                 }
8695
8696                 if (proc.foregroundServices) {
8697                     // Don't kill process(es) with foreground service.
8698                     return;
8699                 }
8700
8701                 // Add process to kill list.
8702                 procsToKill.add(proc);
8703             }
8704         }
8705
8706         // Kill the running processes.
8707         for (int i = 0; i < procsToKill.size(); i++) {
8708             ProcessRecord pr = procsToKill.get(i);
8709             if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
8710                     && pr.curReceiver == null) {
8711                 pr.kill("remove task", true);
8712             } else {
8713                 // We delay killing processes that are not in the background or running a receiver.
8714                 pr.waitingToKill = "remove task";
8715             }
8716         }
8717     }
8718
8719     private void removeTasksByPackageNameLocked(String packageName, int userId) {
8720         // Remove all tasks with activities in the specified package from the list of recent tasks
8721         for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
8722             TaskRecord tr = mRecentTasks.get(i);
8723             if (tr.userId != userId) continue;
8724
8725             ComponentName cn = tr.intent.getComponent();
8726             if (cn != null && cn.getPackageName().equals(packageName)) {
8727                 // If the package name matches, remove the task.
8728                 removeTaskByIdLocked(tr.taskId, true);
8729             }
8730         }
8731     }
8732
8733     private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
8734             int userId) {
8735
8736         for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
8737             TaskRecord tr = mRecentTasks.get(i);
8738             if (userId != UserHandle.USER_ALL && tr.userId != userId) {
8739                 continue;
8740             }
8741
8742             ComponentName cn = tr.intent.getComponent();
8743             final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
8744                     && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
8745             if (sameComponent) {
8746                 removeTaskByIdLocked(tr.taskId, false);
8747             }
8748         }
8749     }
8750
8751     /**
8752      * Removes the task with the specified task id.
8753      *
8754      * @param taskId Identifier of the task to be removed.
8755      * @param killProcess Kill any process associated with the task if possible.
8756      * @return Returns true if the given task was found and removed.
8757      */
8758     private boolean removeTaskByIdLocked(int taskId, boolean killProcess) {
8759         TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(taskId, false);
8760         if (tr != null) {
8761             tr.removeTaskActivitiesLocked();
8762             cleanUpRemovedTaskLocked(tr, killProcess);
8763             if (tr.isPersistable) {
8764                 notifyTaskPersisterLocked(null, true);
8765             }
8766             return true;
8767         }
8768         Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
8769         return false;
8770     }
8771
8772     @Override
8773     public boolean removeTask(int taskId) {
8774         synchronized (this) {
8775             enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
8776                     "removeTask()");
8777             long ident = Binder.clearCallingIdentity();
8778             try {
8779                 return removeTaskByIdLocked(taskId, true);
8780             } finally {
8781                 Binder.restoreCallingIdentity(ident);
8782             }
8783         }
8784     }
8785
8786     /**
8787      * TODO: Add mController hook
8788      */
8789     @Override
8790     public void moveTaskToFront(int taskId, int flags, Bundle options) {
8791         enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
8792
8793         if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
8794         synchronized(this) {
8795             moveTaskToFrontLocked(taskId, flags, options);
8796         }
8797     }
8798
8799     void moveTaskToFrontLocked(int taskId, int flags, Bundle options) {
8800         if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8801                 Binder.getCallingUid(), -1, -1, "Task to front")) {
8802             ActivityOptions.abort(options);
8803             return;
8804         }
8805         final long origId = Binder.clearCallingIdentity();
8806         try {
8807             final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8808             if (task == null) {
8809                 Slog.d(TAG, "Could not find task for id: "+ taskId);
8810                 return;
8811             }
8812             if (mStackSupervisor.isLockTaskModeViolation(task)) {
8813                 mStackSupervisor.showLockTaskToast();
8814                 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
8815                 return;
8816             }
8817             final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
8818             if (prev != null && prev.isRecentsActivity()) {
8819                 task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
8820             }
8821             mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront");
8822         } finally {
8823             Binder.restoreCallingIdentity(origId);
8824         }
8825         ActivityOptions.abort(options);
8826     }
8827
8828     /**
8829      * Moves an activity, and all of the other activities within the same task, to the bottom
8830      * of the history stack.  The activity's order within the task is unchanged.
8831      *
8832      * @param token A reference to the activity we wish to move
8833      * @param nonRoot If false then this only works if the activity is the root
8834      *                of a task; if true it will work for any activity in a task.
8835      * @return Returns true if the move completed, false if not.
8836      */
8837     @Override
8838     public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
8839         enforceNotIsolatedCaller("moveActivityTaskToBack");
8840         synchronized(this) {
8841             final long origId = Binder.clearCallingIdentity();
8842             try {
8843                 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
8844                 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8845                 if (task != null) {
8846                     if (mStackSupervisor.isLockedTask(task)) {
8847                         mStackSupervisor.showLockTaskToast();
8848                         return false;
8849                     }
8850                     return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
8851                 }
8852             } finally {
8853                 Binder.restoreCallingIdentity(origId);
8854             }
8855         }
8856         return false;
8857     }
8858
8859     @Override
8860     public void moveTaskBackwards(int task) {
8861         enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8862                 "moveTaskBackwards()");
8863
8864         synchronized(this) {
8865             if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8866                     Binder.getCallingUid(), -1, -1, "Task backwards")) {
8867                 return;
8868             }
8869             final long origId = Binder.clearCallingIdentity();
8870             moveTaskBackwardsLocked(task);
8871             Binder.restoreCallingIdentity(origId);
8872         }
8873     }
8874
8875     private final void moveTaskBackwardsLocked(int task) {
8876         Slog.e(TAG, "moveTaskBackwards not yet implemented!");
8877     }
8878
8879     @Override
8880     public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
8881             IActivityContainerCallback callback) throws RemoteException {
8882         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8883                 "createActivityContainer()");
8884         synchronized (this) {
8885             if (parentActivityToken == null) {
8886                 throw new IllegalArgumentException("parent token must not be null");
8887             }
8888             ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
8889             if (r == null) {
8890                 return null;
8891             }
8892             if (callback == null) {
8893                 throw new IllegalArgumentException("callback must not be null");
8894             }
8895             return mStackSupervisor.createVirtualActivityContainer(r, callback);
8896         }
8897     }
8898
8899     @Override
8900     public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
8901         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8902                 "deleteActivityContainer()");
8903         synchronized (this) {
8904             mStackSupervisor.deleteActivityContainer(container);
8905         }
8906     }
8907
8908     @Override
8909     public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
8910         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8911                 "createStackOnDisplay()");
8912         synchronized (this) {
8913             final int stackId = mStackSupervisor.getNextStackId();
8914             final ActivityStack stack = mStackSupervisor.createStackOnDisplay(stackId, displayId);
8915             if (stack == null) {
8916                 return null;
8917             }
8918             return stack.mActivityContainer;
8919         }
8920     }
8921
8922     @Override
8923     public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
8924         synchronized (this) {
8925             ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
8926             if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
8927                 return stack.mActivityContainer.getDisplayId();
8928             }
8929             return Display.DEFAULT_DISPLAY;
8930         }
8931     }
8932
8933     @Override
8934     public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
8935         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8936                 "moveTaskToStack()");
8937         if (stackId == HOME_STACK_ID) {
8938             Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
8939                     new RuntimeException("here").fillInStackTrace());
8940         }
8941         synchronized (this) {
8942             long ident = Binder.clearCallingIdentity();
8943             try {
8944                 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
8945                         + " to stackId=" + stackId + " toTop=" + toTop);
8946                 mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop);
8947             } finally {
8948                 Binder.restoreCallingIdentity(ident);
8949             }
8950         }
8951     }
8952
8953     @Override
8954     public void resizeStack(int stackId, Rect bounds) {
8955         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8956                 "resizeStack()");
8957         long ident = Binder.clearCallingIdentity();
8958         try {
8959             synchronized (this) {
8960                 mStackSupervisor.resizeStackLocked(stackId, bounds);
8961             }
8962         } finally {
8963             Binder.restoreCallingIdentity(ident);
8964         }
8965     }
8966
8967     @Override
8968     public List<StackInfo> getAllStackInfos() {
8969         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8970                 "getAllStackInfos()");
8971         long ident = Binder.clearCallingIdentity();
8972         try {
8973             synchronized (this) {
8974                 return mStackSupervisor.getAllStackInfosLocked();
8975             }
8976         } finally {
8977             Binder.restoreCallingIdentity(ident);
8978         }
8979     }
8980
8981     @Override
8982     public StackInfo getStackInfo(int stackId) {
8983         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8984                 "getStackInfo()");
8985         long ident = Binder.clearCallingIdentity();
8986         try {
8987             synchronized (this) {
8988                 return mStackSupervisor.getStackInfoLocked(stackId);
8989             }
8990         } finally {
8991             Binder.restoreCallingIdentity(ident);
8992         }
8993     }
8994
8995     @Override
8996     public boolean isInHomeStack(int taskId) {
8997         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8998                 "getStackInfo()");
8999         long ident = Binder.clearCallingIdentity();
9000         try {
9001             synchronized (this) {
9002                 TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(taskId, false);
9003                 return tr != null && tr.stack != null && tr.stack.isHomeStack();
9004             }
9005         } finally {
9006             Binder.restoreCallingIdentity(ident);
9007         }
9008     }
9009
9010     @Override
9011     public int getTaskForActivity(IBinder token, boolean onlyRoot) {
9012         synchronized(this) {
9013             return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
9014         }
9015     }
9016
9017     @Override
9018     public void updateDeviceOwner(String packageName) {
9019         final int callingUid = Binder.getCallingUid();
9020         if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
9021             throw new SecurityException("updateDeviceOwner called from non-system process");
9022         }
9023         synchronized (this) {
9024             mDeviceOwnerName = packageName;
9025         }
9026     }
9027
9028     @Override
9029     public void updateLockTaskPackages(int userId, String[] packages) {
9030         final int callingUid = Binder.getCallingUid();
9031         if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
9032             throw new SecurityException("updateLockTaskPackage called from non-system process");
9033         }
9034         synchronized (this) {
9035             if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
9036                     Arrays.toString(packages));
9037             mLockTaskPackages.put(userId, packages);
9038             mStackSupervisor.onLockTaskPackagesUpdatedLocked();
9039         }
9040     }
9041
9042
9043     void startLockTaskModeLocked(TaskRecord task) {
9044         if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
9045         if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
9046             return;
9047         }
9048
9049         // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
9050         // is initiated by system after the pinning request was shown and locked mode is initiated
9051         // by an authorized app directly
9052         final int callingUid = Binder.getCallingUid();
9053         boolean isSystemInitiated = callingUid == Process.SYSTEM_UID;
9054         long ident = Binder.clearCallingIdentity();
9055         try {
9056             final ActivityStack stack = mStackSupervisor.getFocusedStack();
9057             if (!isSystemInitiated) {
9058                 task.mLockTaskUid = callingUid;
9059                 if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
9060                     // startLockTask() called by app and task mode is lockTaskModeDefault.
9061                     if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
9062                     StatusBarManagerInternal statusBarManager =
9063                             LocalServices.getService(StatusBarManagerInternal.class);
9064                     if (statusBarManager != null) {
9065                         statusBarManager.showScreenPinningRequest();
9066                     }
9067                     return;
9068                 }
9069
9070                 if (stack == null || task != stack.topTask()) {
9071                     throw new IllegalArgumentException("Invalid task, not in foreground");
9072                 }
9073             }
9074             if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
9075                     "Locking fully");
9076             mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
9077                     ActivityManager.LOCK_TASK_MODE_PINNED :
9078                     ActivityManager.LOCK_TASK_MODE_LOCKED,
9079                     "startLockTask", true);
9080         } finally {
9081             Binder.restoreCallingIdentity(ident);
9082         }
9083     }
9084
9085     @Override
9086     public void startLockTaskMode(int taskId) {
9087         synchronized (this) {
9088             final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9089             if (task != null) {
9090                 startLockTaskModeLocked(task);
9091             }
9092         }
9093     }
9094
9095     @Override
9096     public void startLockTaskMode(IBinder token) {
9097         synchronized (this) {
9098             final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9099             if (r == null) {
9100                 return;
9101             }
9102             final TaskRecord task = r.task;
9103             if (task != null) {
9104                 startLockTaskModeLocked(task);
9105             }
9106         }
9107     }
9108
9109     @Override
9110     public void startLockTaskModeOnCurrent() throws RemoteException {
9111         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9112                 "startLockTaskModeOnCurrent");
9113         long ident = Binder.clearCallingIdentity();
9114         try {
9115             synchronized (this) {
9116                 ActivityRecord r = mStackSupervisor.topRunningActivityLocked();
9117                 if (r != null) {
9118                     startLockTaskModeLocked(r.task);
9119                 }
9120             }
9121         } finally {
9122             Binder.restoreCallingIdentity(ident);
9123         }
9124     }
9125
9126     @Override
9127     public void stopLockTaskMode() {
9128         final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
9129         if (lockTask == null) {
9130             // Our work here is done.
9131             return;
9132         }
9133
9134         final int callingUid = Binder.getCallingUid();
9135         final int lockTaskUid = lockTask.mLockTaskUid;
9136         // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
9137         // It is possible lockTaskMode was started by the system process because
9138         // android:lockTaskMode is set to a locking value in the application manifest instead of
9139         // the app calling startLockTaskMode. In this case {@link TaskRecord.mLockTaskUid} will
9140         // be 0, so we compare the callingUid to the {@link TaskRecord.effectiveUid} instead.
9141         if (getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_LOCKED &&
9142                 callingUid != lockTaskUid
9143                 && (lockTaskUid != 0
9144                     || (lockTaskUid == 0 && callingUid != lockTask.effectiveUid))) {
9145             throw new SecurityException("Invalid uid, expected " + lockTaskUid
9146                     + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
9147         }
9148
9149         long ident = Binder.clearCallingIdentity();
9150         try {
9151             Log.d(TAG, "stopLockTaskMode");
9152             // Stop lock task
9153             synchronized (this) {
9154                 mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
9155                         "stopLockTask", true);
9156             }
9157         } finally {
9158             Binder.restoreCallingIdentity(ident);
9159         }
9160     }
9161
9162     @Override
9163     public void stopLockTaskModeOnCurrent() throws RemoteException {
9164         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9165                 "stopLockTaskModeOnCurrent");
9166         long ident = Binder.clearCallingIdentity();
9167         try {
9168             stopLockTaskMode();
9169         } finally {
9170             Binder.restoreCallingIdentity(ident);
9171         }
9172     }
9173
9174     @Override
9175     public boolean isInLockTaskMode() {
9176         return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
9177     }
9178
9179     @Override
9180     public int getLockTaskModeState() {
9181         synchronized (this) {
9182             return mStackSupervisor.getLockTaskModeState();
9183         }
9184     }
9185
9186     @Override
9187     public void showLockTaskEscapeMessage(IBinder token) {
9188         synchronized (this) {
9189             final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9190             if (r == null) {
9191                 return;
9192             }
9193             mStackSupervisor.showLockTaskEscapeMessageLocked(r.task);
9194         }
9195     }
9196
9197     // =========================================================
9198     // CONTENT PROVIDERS
9199     // =========================================================
9200
9201     private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
9202         List<ProviderInfo> providers = null;
9203         try {
9204             ParceledListSlice<ProviderInfo> slice = AppGlobals.getPackageManager().
9205                 queryContentProviders(app.processName, app.uid,
9206                         STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
9207             providers = slice != null ? slice.getList() : null;
9208         } catch (RemoteException ex) {
9209         }
9210         if (DEBUG_MU) Slog.v(TAG_MU,
9211                 "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
9212         int userId = app.userId;
9213         if (providers != null) {
9214             int N = providers.size();
9215             app.pubProviders.ensureCapacity(N + app.pubProviders.size());
9216             for (int i=0; i<N; i++) {
9217                 ProviderInfo cpi =
9218                     (ProviderInfo)providers.get(i);
9219                 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9220                         cpi.name, cpi.flags);
9221                 if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_OWNER) {
9222                     // This is a singleton provider, but a user besides the
9223                     // default user is asking to initialize a process it runs
9224                     // in...  well, no, it doesn't actually run in this process,
9225                     // it runs in the process of the default user.  Get rid of it.
9226                     providers.remove(i);
9227                     N--;
9228                     i--;
9229                     continue;
9230                 }
9231
9232                 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9233                 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
9234                 if (cpr == null) {
9235                     cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
9236                     mProviderMap.putProviderByClass(comp, cpr);
9237                 }
9238                 if (DEBUG_MU) Slog.v(TAG_MU,
9239                         "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
9240                 app.pubProviders.put(cpi.name, cpr);
9241                 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
9242                     // Don't add this if it is a platform component that is marked
9243                     // to run in multiple processes, because this is actually
9244                     // part of the framework so doesn't make sense to track as a
9245                     // separate apk in the process.
9246                     app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
9247                             mProcessStats);
9248                 }
9249                 ensurePackageDexOpt(cpi.applicationInfo.packageName);
9250             }
9251         }
9252         return providers;
9253     }
9254
9255     /**
9256      * Check if {@link ProcessRecord} has a possible chance at accessing the
9257      * given {@link ProviderInfo}. Final permission checking is always done
9258      * in {@link ContentProvider}.
9259      */
9260     private final String checkContentProviderPermissionLocked(
9261             ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
9262         final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
9263         final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
9264         boolean checkedGrants = false;
9265         if (checkUser) {
9266             // Looking for cross-user grants before enforcing the typical cross-users permissions
9267             int tmpTargetUserId = unsafeConvertIncomingUser(userId);
9268             if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
9269                 if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
9270                     return null;
9271                 }
9272                 checkedGrants = true;
9273             }
9274             userId = handleIncomingUser(callingPid, callingUid, userId,
9275                     false, ALLOW_NON_FULL,
9276                     "checkContentProviderPermissionLocked " + cpi.authority, null);
9277             if (userId != tmpTargetUserId) {
9278                 // When we actually went to determine the final targer user ID, this ended
9279                 // up different than our initial check for the authority.  This is because
9280                 // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
9281                 // SELF.  So we need to re-check the grants again.
9282                 checkedGrants = false;
9283             }
9284         }
9285         if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
9286                 cpi.applicationInfo.uid, cpi.exported)
9287                 == PackageManager.PERMISSION_GRANTED) {
9288             return null;
9289         }
9290         if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
9291                 cpi.applicationInfo.uid, cpi.exported)
9292                 == PackageManager.PERMISSION_GRANTED) {
9293             return null;
9294         }
9295
9296         PathPermission[] pps = cpi.pathPermissions;
9297         if (pps != null) {
9298             int i = pps.length;
9299             while (i > 0) {
9300                 i--;
9301                 PathPermission pp = pps[i];
9302                 String pprperm = pp.getReadPermission();
9303                 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
9304                         cpi.applicationInfo.uid, cpi.exported)
9305                         == PackageManager.PERMISSION_GRANTED) {
9306                     return null;
9307                 }
9308                 String ppwperm = pp.getWritePermission();
9309                 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
9310                         cpi.applicationInfo.uid, cpi.exported)
9311                         == PackageManager.PERMISSION_GRANTED) {
9312                     return null;
9313                 }
9314             }
9315         }
9316         if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
9317             return null;
9318         }
9319
9320         String msg;
9321         if (!cpi.exported) {
9322             msg = "Permission Denial: opening provider " + cpi.name
9323                     + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9324                     + ", uid=" + callingUid + ") that is not exported from uid "
9325                     + cpi.applicationInfo.uid;
9326         } else {
9327             msg = "Permission Denial: opening provider " + cpi.name
9328                     + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9329                     + ", uid=" + callingUid + ") requires "
9330                     + cpi.readPermission + " or " + cpi.writePermission;
9331         }
9332         Slog.w(TAG, msg);
9333         return msg;
9334     }
9335
9336     /**
9337      * Returns if the ContentProvider has granted a uri to callingUid
9338      */
9339     boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
9340         final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
9341         if (perms != null) {
9342             for (int i=perms.size()-1; i>=0; i--) {
9343                 GrantUri grantUri = perms.keyAt(i);
9344                 if (grantUri.sourceUserId == userId || !checkUser) {
9345                     if (matchesProvider(grantUri.uri, cpi)) {
9346                         return true;
9347                     }
9348                 }
9349             }
9350         }
9351         return false;
9352     }
9353
9354     /**
9355      * Returns true if the uri authority is one of the authorities specified in the provider.
9356      */
9357     boolean matchesProvider(Uri uri, ProviderInfo cpi) {
9358         String uriAuth = uri.getAuthority();
9359         String cpiAuth = cpi.authority;
9360         if (cpiAuth.indexOf(';') == -1) {
9361             return cpiAuth.equals(uriAuth);
9362         }
9363         String[] cpiAuths = cpiAuth.split(";");
9364         int length = cpiAuths.length;
9365         for (int i = 0; i < length; i++) {
9366             if (cpiAuths[i].equals(uriAuth)) return true;
9367         }
9368         return false;
9369     }
9370
9371     ContentProviderConnection incProviderCountLocked(ProcessRecord r,
9372             final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9373         if (r != null) {
9374             for (int i=0; i<r.conProviders.size(); i++) {
9375                 ContentProviderConnection conn = r.conProviders.get(i);
9376                 if (conn.provider == cpr) {
9377                     if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
9378                             "Adding provider requested by "
9379                             + r.processName + " from process "
9380                             + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9381                             + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9382                     if (stable) {
9383                         conn.stableCount++;
9384                         conn.numStableIncs++;
9385                     } else {
9386                         conn.unstableCount++;
9387                         conn.numUnstableIncs++;
9388                     }
9389                     return conn;
9390                 }
9391             }
9392             ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
9393             if (stable) {
9394                 conn.stableCount = 1;
9395                 conn.numStableIncs = 1;
9396             } else {
9397                 conn.unstableCount = 1;
9398                 conn.numUnstableIncs = 1;
9399             }
9400             cpr.connections.add(conn);
9401             r.conProviders.add(conn);
9402             startAssociationLocked(r.uid, r.processName, cpr.uid, cpr.name, cpr.info.processName);
9403             return conn;
9404         }
9405         cpr.addExternalProcessHandleLocked(externalProcessToken);
9406         return null;
9407     }
9408
9409     boolean decProviderCountLocked(ContentProviderConnection conn,
9410             ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9411         if (conn != null) {
9412             cpr = conn.provider;
9413             if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
9414                     "Removing provider requested by "
9415                     + conn.client.processName + " from process "
9416                     + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9417                     + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9418             if (stable) {
9419                 conn.stableCount--;
9420             } else {
9421                 conn.unstableCount--;
9422             }
9423             if (conn.stableCount == 0 && conn.unstableCount == 0) {
9424                 cpr.connections.remove(conn);
9425                 conn.client.conProviders.remove(conn);
9426                 stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
9427                 return true;
9428             }
9429             return false;
9430         }
9431         cpr.removeExternalProcessHandleLocked(externalProcessToken);
9432         return false;
9433     }
9434
9435     private void checkTime(long startTime, String where) {
9436         long now = SystemClock.elapsedRealtime();
9437         if ((now-startTime) > 1000) {
9438             // If we are taking more than a second, log about it.
9439             Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
9440         }
9441     }
9442
9443     private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
9444             String name, IBinder token, boolean stable, int userId) {
9445         ContentProviderRecord cpr;
9446         ContentProviderConnection conn = null;
9447         ProviderInfo cpi = null;
9448
9449         synchronized(this) {
9450             long startTime = SystemClock.elapsedRealtime();
9451
9452             ProcessRecord r = null;
9453             if (caller != null) {
9454                 r = getRecordForAppLocked(caller);
9455                 if (r == null) {
9456                     throw new SecurityException(
9457                             "Unable to find app for caller " + caller
9458                           + " (pid=" + Binder.getCallingPid()
9459                           + ") when getting content provider " + name);
9460                 }
9461             }
9462
9463             boolean checkCrossUser = true;
9464
9465             checkTime(startTime, "getContentProviderImpl: getProviderByName");
9466
9467             // First check if this content provider has been published...
9468             cpr = mProviderMap.getProviderByName(name, userId);
9469             // If that didn't work, check if it exists for user 0 and then
9470             // verify that it's a singleton provider before using it.
9471             if (cpr == null && userId != UserHandle.USER_OWNER) {
9472                 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
9473                 if (cpr != null) {
9474                     cpi = cpr.info;
9475                     if (isSingleton(cpi.processName, cpi.applicationInfo,
9476                             cpi.name, cpi.flags)
9477                             && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
9478                         userId = UserHandle.USER_OWNER;
9479                         checkCrossUser = false;
9480                     } else {
9481                         cpr = null;
9482                         cpi = null;
9483                     }
9484                 }
9485             }
9486
9487             boolean providerRunning = cpr != null;
9488             if (providerRunning) {
9489                 cpi = cpr.info;
9490                 String msg;
9491                 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9492                 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
9493                         != null) {
9494                     throw new SecurityException(msg);
9495                 }
9496                 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9497
9498                 if (r != null && cpr.canRunHere(r)) {
9499                     // This provider has been published or is in the process
9500                     // of being published...  but it is also allowed to run
9501                     // in the caller's process, so don't make a connection
9502                     // and just let the caller instantiate its own instance.
9503                     ContentProviderHolder holder = cpr.newHolder(null);
9504                     // don't give caller the provider object, it needs
9505                     // to make its own.
9506                     holder.provider = null;
9507                     return holder;
9508                 }
9509
9510                 final long origId = Binder.clearCallingIdentity();
9511
9512                 checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
9513
9514                 // In this case the provider instance already exists, so we can
9515                 // return it right away.
9516                 conn = incProviderCountLocked(r, cpr, token, stable);
9517                 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
9518                     if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
9519                         // If this is a perceptible app accessing the provider,
9520                         // make sure to count it as being accessed and thus
9521                         // back up on the LRU list.  This is good because
9522                         // content providers are often expensive to start.
9523                         checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
9524                         updateLruProcessLocked(cpr.proc, false, null);
9525                         checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
9526                     }
9527                 }
9528
9529                 if (cpr.proc != null) {
9530                     if (false) {
9531                         if (cpr.name.flattenToShortString().equals(
9532                                 "com.android.providers.calendar/.CalendarProvider2")) {
9533                             Slog.v(TAG, "****************** KILLING "
9534                                 + cpr.name.flattenToShortString());
9535                             Process.killProcess(cpr.proc.pid);
9536                         }
9537                     }
9538                     checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
9539                     boolean success = updateOomAdjLocked(cpr.proc);
9540                     maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
9541                     checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
9542                     if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
9543                     // NOTE: there is still a race here where a signal could be
9544                     // pending on the process even though we managed to update its
9545                     // adj level.  Not sure what to do about this, but at least
9546                     // the race is now smaller.
9547                     if (!success) {
9548                         // Uh oh...  it looks like the provider's process
9549                         // has been killed on us.  We need to wait for a new
9550                         // process to be started, and make sure its death
9551                         // doesn't kill our process.
9552                         Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
9553                                 + " is crashing; detaching " + r);
9554                         boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
9555                         checkTime(startTime, "getContentProviderImpl: before appDied");
9556                         appDiedLocked(cpr.proc);
9557                         checkTime(startTime, "getContentProviderImpl: after appDied");
9558                         if (!lastRef) {
9559                             // This wasn't the last ref our process had on
9560                             // the provider...  we have now been killed, bail.
9561                             return null;
9562                         }
9563                         providerRunning = false;
9564                         conn = null;
9565                     }
9566                 }
9567
9568                 Binder.restoreCallingIdentity(origId);
9569             }
9570
9571             boolean singleton;
9572             if (!providerRunning) {
9573                 try {
9574                     checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
9575                     cpi = AppGlobals.getPackageManager().
9576                         resolveContentProvider(name,
9577                             STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
9578                     checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
9579                 } catch (RemoteException ex) {
9580                 }
9581                 if (cpi == null) {
9582                     return null;
9583                 }
9584                 // If the provider is a singleton AND
9585                 // (it's a call within the same user || the provider is a
9586                 // privileged app)
9587                 // Then allow connecting to the singleton provider
9588                 singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9589                         cpi.name, cpi.flags)
9590                         && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
9591                 if (singleton) {
9592                     userId = UserHandle.USER_OWNER;
9593                 }
9594                 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
9595                 checkTime(startTime, "getContentProviderImpl: got app info for user");
9596
9597                 String msg;
9598                 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9599                 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
9600                         != null) {
9601                     throw new SecurityException(msg);
9602                 }
9603                 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9604
9605                 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
9606                         && !cpi.processName.equals("system")) {
9607                     // If this content provider does not run in the system
9608                     // process, and the system is not yet ready to run other
9609                     // processes, then fail fast instead of hanging.
9610                     throw new IllegalArgumentException(
9611                             "Attempt to launch content provider before system ready");
9612                 }
9613
9614                 // Make sure that the user who owns this provider is running.  If not,
9615                 // we don't want to allow it to run.
9616                 if (!isUserRunningLocked(userId, false)) {
9617                     Slog.w(TAG, "Unable to launch app "
9618                             + cpi.applicationInfo.packageName + "/"
9619                             + cpi.applicationInfo.uid + " for provider "
9620                             + name + ": user " + userId + " is stopped");
9621                     return null;
9622                 }
9623
9624                 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9625                 checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
9626                 cpr = mProviderMap.getProviderByClass(comp, userId);
9627                 checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
9628                 final boolean firstClass = cpr == null;
9629                 if (firstClass) {
9630                     final long ident = Binder.clearCallingIdentity();
9631                     try {
9632                         checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
9633                         ApplicationInfo ai =
9634                             AppGlobals.getPackageManager().
9635                                 getApplicationInfo(
9636                                         cpi.applicationInfo.packageName,
9637                                         STOCK_PM_FLAGS, userId);
9638                         checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
9639                         if (ai == null) {
9640                             Slog.w(TAG, "No package info for content provider "
9641                                     + cpi.name);
9642                             return null;
9643                         }
9644                         ai = getAppInfoForUser(ai, userId);
9645                         cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
9646                     } catch (RemoteException ex) {
9647                         // pm is in same process, this will never happen.
9648                     } finally {
9649                         Binder.restoreCallingIdentity(ident);
9650                     }
9651                 }
9652
9653                 checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
9654
9655                 if (r != null && cpr.canRunHere(r)) {
9656                     // If this is a multiprocess provider, then just return its
9657                     // info and allow the caller to instantiate it.  Only do
9658                     // this if the provider is the same user as the caller's
9659                     // process, or can run as root (so can be in any process).
9660                     return cpr.newHolder(null);
9661                 }
9662
9663                 if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
9664                             + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
9665                             + cpr.info.name + " callers=" + Debug.getCallers(6));
9666
9667                 // This is single process, and our app is now connecting to it.
9668                 // See if we are already in the process of launching this
9669                 // provider.
9670                 final int N = mLaunchingProviders.size();
9671                 int i;
9672                 for (i = 0; i < N; i++) {
9673                     if (mLaunchingProviders.get(i) == cpr) {
9674                         break;
9675                     }
9676                 }
9677
9678                 // If the provider is not already being launched, then get it
9679                 // started.
9680                 if (i >= N) {
9681                     final long origId = Binder.clearCallingIdentity();
9682
9683                     try {
9684                         // Content provider is now in use, its package can't be stopped.
9685                         try {
9686                             checkTime(startTime, "getContentProviderImpl: before set stopped state");
9687                             AppGlobals.getPackageManager().setPackageStoppedState(
9688                                     cpr.appInfo.packageName, false, userId);
9689                             checkTime(startTime, "getContentProviderImpl: after set stopped state");
9690                         } catch (RemoteException e) {
9691                         } catch (IllegalArgumentException e) {
9692                             Slog.w(TAG, "Failed trying to unstop package "
9693                                     + cpr.appInfo.packageName + ": " + e);
9694                         }
9695
9696                         // Use existing process if already started
9697                         checkTime(startTime, "getContentProviderImpl: looking for process record");
9698                         ProcessRecord proc = getProcessRecordLocked(
9699                                 cpi.processName, cpr.appInfo.uid, false);
9700                         if (proc != null && proc.thread != null) {
9701                             if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
9702                                     "Installing in existing process " + proc);
9703                             if (!proc.pubProviders.containsKey(cpi.name)) {
9704                                 checkTime(startTime, "getContentProviderImpl: scheduling install");
9705                                 proc.pubProviders.put(cpi.name, cpr);
9706                                 try {
9707                                     proc.thread.scheduleInstallProvider(cpi);
9708                                 } catch (RemoteException e) {
9709                                 }
9710                             }
9711                         } else {
9712                             checkTime(startTime, "getContentProviderImpl: before start process");
9713                             proc = startProcessLocked(cpi.processName,
9714                                     cpr.appInfo, false, 0, "content provider",
9715                                     new ComponentName(cpi.applicationInfo.packageName,
9716                                             cpi.name), false, false, false);
9717                             checkTime(startTime, "getContentProviderImpl: after start process");
9718                             if (proc == null) {
9719                                 Slog.w(TAG, "Unable to launch app "
9720                                         + cpi.applicationInfo.packageName + "/"
9721                                         + cpi.applicationInfo.uid + " for provider "
9722                                         + name + ": process is bad");
9723                                 return null;
9724                             }
9725                         }
9726                         cpr.launchingApp = proc;
9727                         mLaunchingProviders.add(cpr);
9728                     } finally {
9729                         Binder.restoreCallingIdentity(origId);
9730                     }
9731                 }
9732
9733                 checkTime(startTime, "getContentProviderImpl: updating data structures");
9734
9735                 // Make sure the provider is published (the same provider class
9736                 // may be published under multiple names).
9737                 if (firstClass) {
9738                     mProviderMap.putProviderByClass(comp, cpr);
9739                 }
9740
9741                 mProviderMap.putProviderByName(name, cpr);
9742                 conn = incProviderCountLocked(r, cpr, token, stable);
9743                 if (conn != null) {
9744                     conn.waiting = true;
9745                 }
9746             }
9747             checkTime(startTime, "getContentProviderImpl: done!");
9748         }
9749
9750         // Wait for the provider to be published...
9751         synchronized (cpr) {
9752             while (cpr.provider == null) {
9753                 if (cpr.launchingApp == null) {
9754                     Slog.w(TAG, "Unable to launch app "
9755                             + cpi.applicationInfo.packageName + "/"
9756                             + cpi.applicationInfo.uid + " for provider "
9757                             + name + ": launching app became null");
9758                     EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
9759                             UserHandle.getUserId(cpi.applicationInfo.uid),
9760                             cpi.applicationInfo.packageName,
9761                             cpi.applicationInfo.uid, name);
9762                     return null;
9763                 }
9764                 try {
9765                     if (DEBUG_MU) Slog.v(TAG_MU,
9766                             "Waiting to start provider " + cpr
9767                             + " launchingApp=" + cpr.launchingApp);
9768                     if (conn != null) {
9769                         conn.waiting = true;
9770                     }
9771                     cpr.wait();
9772                 } catch (InterruptedException ex) {
9773                 } finally {
9774                     if (conn != null) {
9775                         conn.waiting = false;
9776                     }
9777                 }
9778             }
9779         }
9780         return cpr != null ? cpr.newHolder(conn) : null;
9781     }
9782
9783     @Override
9784     public final ContentProviderHolder getContentProvider(
9785             IApplicationThread caller, String name, int userId, boolean stable) {
9786         enforceNotIsolatedCaller("getContentProvider");
9787         if (caller == null) {
9788             String msg = "null IApplicationThread when getting content provider "
9789                     + name;
9790             Slog.w(TAG, msg);
9791             throw new SecurityException(msg);
9792         }
9793         // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
9794         // with cross-user grant.
9795         return getContentProviderImpl(caller, name, null, stable, userId);
9796     }
9797
9798     public ContentProviderHolder getContentProviderExternal(
9799             String name, int userId, IBinder token) {
9800         enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9801             "Do not have permission in call getContentProviderExternal()");
9802         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
9803                 false, ALLOW_FULL_ONLY, "getContentProvider", null);
9804         return getContentProviderExternalUnchecked(name, token, userId);
9805     }
9806
9807     private ContentProviderHolder getContentProviderExternalUnchecked(String name,
9808             IBinder token, int userId) {
9809         return getContentProviderImpl(null, name, token, true, userId);
9810     }
9811
9812     /**
9813      * Drop a content provider from a ProcessRecord's bookkeeping
9814      */
9815     public void removeContentProvider(IBinder connection, boolean stable) {
9816         enforceNotIsolatedCaller("removeContentProvider");
9817         long ident = Binder.clearCallingIdentity();
9818         try {
9819             synchronized (this) {
9820                 ContentProviderConnection conn;
9821                 try {
9822                     conn = (ContentProviderConnection)connection;
9823                 } catch (ClassCastException e) {
9824                     String msg ="removeContentProvider: " + connection
9825                             + " not a ContentProviderConnection";
9826                     Slog.w(TAG, msg);
9827                     throw new IllegalArgumentException(msg);
9828                 }
9829                 if (conn == null) {
9830                     throw new NullPointerException("connection is null");
9831                 }
9832                 if (decProviderCountLocked(conn, null, null, stable)) {
9833                     updateOomAdjLocked();
9834                 }
9835             }
9836         } finally {
9837             Binder.restoreCallingIdentity(ident);
9838         }
9839     }
9840
9841     public void removeContentProviderExternal(String name, IBinder token) {
9842         enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9843             "Do not have permission in call removeContentProviderExternal()");
9844         int userId = UserHandle.getCallingUserId();
9845         long ident = Binder.clearCallingIdentity();
9846         try {
9847             removeContentProviderExternalUnchecked(name, token, userId);
9848         } finally {
9849             Binder.restoreCallingIdentity(ident);
9850         }
9851     }
9852
9853     private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
9854         synchronized (this) {
9855             ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
9856             if(cpr == null) {
9857                 //remove from mProvidersByClass
9858                 if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
9859                 return;
9860             }
9861
9862             //update content provider record entry info
9863             ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
9864             ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
9865             if (localCpr.hasExternalProcessHandles()) {
9866                 if (localCpr.removeExternalProcessHandleLocked(token)) {
9867                     updateOomAdjLocked();
9868                 } else {
9869                     Slog.e(TAG, "Attmpt to remove content provider " + localCpr
9870                             + " with no external reference for token: "
9871                             + token + ".");
9872                 }
9873             } else {
9874                 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
9875                         + " with no external references.");
9876             }
9877         }
9878     }
9879
9880     public final void publishContentProviders(IApplicationThread caller,
9881             List<ContentProviderHolder> providers) {
9882         if (providers == null) {
9883             return;
9884         }
9885
9886         enforceNotIsolatedCaller("publishContentProviders");
9887         synchronized (this) {
9888             final ProcessRecord r = getRecordForAppLocked(caller);
9889             if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
9890             if (r == null) {
9891                 throw new SecurityException(
9892                         "Unable to find app for caller " + caller
9893                       + " (pid=" + Binder.getCallingPid()
9894                       + ") when publishing content providers");
9895             }
9896
9897             final long origId = Binder.clearCallingIdentity();
9898
9899             final int N = providers.size();
9900             for (int i=0; i<N; i++) {
9901                 ContentProviderHolder src = providers.get(i);
9902                 if (src == null || src.info == null || src.provider == null) {
9903                     continue;
9904                 }
9905                 ContentProviderRecord dst = r.pubProviders.get(src.info.name);
9906                 if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
9907                 if (dst != null) {
9908                     ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
9909                     mProviderMap.putProviderByClass(comp, dst);
9910                     String names[] = dst.info.authority.split(";");
9911                     for (int j = 0; j < names.length; j++) {
9912                         mProviderMap.putProviderByName(names[j], dst);
9913                     }
9914
9915                     int NL = mLaunchingProviders.size();
9916                     int j;
9917                     for (j=0; j<NL; j++) {
9918                         if (mLaunchingProviders.get(j) == dst) {
9919                             mLaunchingProviders.remove(j);
9920                             j--;
9921                             NL--;
9922                         }
9923                     }
9924                     synchronized (dst) {
9925                         dst.provider = src.provider;
9926                         dst.proc = r;
9927                         dst.notifyAll();
9928                     }
9929                     updateOomAdjLocked(r);
9930                     maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
9931                             src.info.authority);
9932                 }
9933             }
9934
9935             Binder.restoreCallingIdentity(origId);
9936         }
9937     }
9938
9939     public boolean refContentProvider(IBinder connection, int stable, int unstable) {
9940         ContentProviderConnection conn;
9941         try {
9942             conn = (ContentProviderConnection)connection;
9943         } catch (ClassCastException e) {
9944             String msg ="refContentProvider: " + connection
9945                     + " not a ContentProviderConnection";
9946             Slog.w(TAG, msg);
9947             throw new IllegalArgumentException(msg);
9948         }
9949         if (conn == null) {
9950             throw new NullPointerException("connection is null");
9951         }
9952
9953         synchronized (this) {
9954             if (stable > 0) {
9955                 conn.numStableIncs += stable;
9956             }
9957             stable = conn.stableCount + stable;
9958             if (stable < 0) {
9959                 throw new IllegalStateException("stableCount < 0: " + stable);
9960             }
9961
9962             if (unstable > 0) {
9963                 conn.numUnstableIncs += unstable;
9964             }
9965             unstable = conn.unstableCount + unstable;
9966             if (unstable < 0) {
9967                 throw new IllegalStateException("unstableCount < 0: " + unstable);
9968             }
9969
9970             if ((stable+unstable) <= 0) {
9971                 throw new IllegalStateException("ref counts can't go to zero here: stable="
9972                         + stable + " unstable=" + unstable);
9973             }
9974             conn.stableCount = stable;
9975             conn.unstableCount = unstable;
9976             return !conn.dead;
9977         }
9978     }
9979
9980     public void unstableProviderDied(IBinder connection) {
9981         ContentProviderConnection conn;
9982         try {
9983             conn = (ContentProviderConnection)connection;
9984         } catch (ClassCastException e) {
9985             String msg ="refContentProvider: " + connection
9986                     + " not a ContentProviderConnection";
9987             Slog.w(TAG, msg);
9988             throw new IllegalArgumentException(msg);
9989         }
9990         if (conn == null) {
9991             throw new NullPointerException("connection is null");
9992         }
9993
9994         // Safely retrieve the content provider associated with the connection.
9995         IContentProvider provider;
9996         synchronized (this) {
9997             provider = conn.provider.provider;
9998         }
9999
10000         if (provider == null) {
10001             // Um, yeah, we're way ahead of you.
10002             return;
10003         }
10004
10005         // Make sure the caller is being honest with us.
10006         if (provider.asBinder().pingBinder()) {
10007             // Er, no, still looks good to us.
10008             synchronized (this) {
10009                 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
10010                         + " says " + conn + " died, but we don't agree");
10011                 return;
10012             }
10013         }
10014
10015         // Well look at that!  It's dead!
10016         synchronized (this) {
10017             if (conn.provider.provider != provider) {
10018                 // But something changed...  good enough.
10019                 return;
10020             }
10021
10022             ProcessRecord proc = conn.provider.proc;
10023             if (proc == null || proc.thread == null) {
10024                 // Seems like the process is already cleaned up.
10025                 return;
10026             }
10027
10028             // As far as we're concerned, this is just like receiving a
10029             // death notification...  just a bit prematurely.
10030             Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
10031                     + ") early provider death");
10032             final long ident = Binder.clearCallingIdentity();
10033             try {
10034                 appDiedLocked(proc);
10035             } finally {
10036                 Binder.restoreCallingIdentity(ident);
10037             }
10038         }
10039     }
10040
10041     @Override
10042     public void appNotRespondingViaProvider(IBinder connection) {
10043         enforceCallingPermission(
10044                 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
10045
10046         final ContentProviderConnection conn = (ContentProviderConnection) connection;
10047         if (conn == null) {
10048             Slog.w(TAG, "ContentProviderConnection is null");
10049             return;
10050         }
10051
10052         final ProcessRecord host = conn.provider.proc;
10053         if (host == null) {
10054             Slog.w(TAG, "Failed to find hosting ProcessRecord");
10055             return;
10056         }
10057
10058         final long token = Binder.clearCallingIdentity();
10059         try {
10060             appNotResponding(host, null, null, false, "ContentProvider not responding");
10061         } finally {
10062             Binder.restoreCallingIdentity(token);
10063         }
10064     }
10065
10066     public final void installSystemProviders() {
10067         List<ProviderInfo> providers;
10068         synchronized (this) {
10069             ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
10070             providers = generateApplicationProvidersLocked(app);
10071             if (providers != null) {
10072                 for (int i=providers.size()-1; i>=0; i--) {
10073                     ProviderInfo pi = (ProviderInfo)providers.get(i);
10074                     if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
10075                         Slog.w(TAG, "Not installing system proc provider " + pi.name
10076                                 + ": not system .apk");
10077                         providers.remove(i);
10078                     }
10079                 }
10080             }
10081         }
10082         if (providers != null) {
10083             mSystemThread.installSystemProviders(providers);
10084         }
10085
10086         mCoreSettingsObserver = new CoreSettingsObserver(this);
10087
10088         //mUsageStatsService.monitorPackages();
10089     }
10090
10091     /**
10092      * Allows apps to retrieve the MIME type of a URI.
10093      * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
10094      * users, then it does not need permission to access the ContentProvider.
10095      * Either, it needs cross-user uri grants.
10096      *
10097      * CTS tests for this functionality can be run with "runtest cts-appsecurity".
10098      *
10099      * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
10100      *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
10101      */
10102     public String getProviderMimeType(Uri uri, int userId) {
10103         enforceNotIsolatedCaller("getProviderMimeType");
10104         final String name = uri.getAuthority();
10105         int callingUid = Binder.getCallingUid();
10106         int callingPid = Binder.getCallingPid();
10107         long ident = 0;
10108         boolean clearedIdentity = false;
10109         userId = unsafeConvertIncomingUser(userId);
10110         if (canClearIdentity(callingPid, callingUid, userId)) {
10111             clearedIdentity = true;
10112             ident = Binder.clearCallingIdentity();
10113         }
10114         ContentProviderHolder holder = null;
10115         try {
10116             holder = getContentProviderExternalUnchecked(name, null, userId);
10117             if (holder != null) {
10118                 return holder.provider.getType(uri);
10119             }
10120         } catch (RemoteException e) {
10121             Log.w(TAG, "Content provider dead retrieving " + uri, e);
10122             return null;
10123         } finally {
10124             // We need to clear the identity to call removeContentProviderExternalUnchecked
10125             if (!clearedIdentity) {
10126                 ident = Binder.clearCallingIdentity();
10127             }
10128             try {
10129                 if (holder != null) {
10130                     removeContentProviderExternalUnchecked(name, null, userId);
10131                 }
10132             } finally {
10133                 Binder.restoreCallingIdentity(ident);
10134             }
10135         }
10136
10137         return null;
10138     }
10139
10140     private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
10141         if (UserHandle.getUserId(callingUid) == userId) {
10142             return true;
10143         }
10144         if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
10145                 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
10146                 || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
10147                 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
10148                 return true;
10149         }
10150         return false;
10151     }
10152
10153     // =========================================================
10154     // GLOBAL MANAGEMENT
10155     // =========================================================
10156
10157     final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
10158             boolean isolated, int isolatedUid) {
10159         String proc = customProcess != null ? customProcess : info.processName;
10160         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10161         final int userId = UserHandle.getUserId(info.uid);
10162         int uid = info.uid;
10163         if (isolated) {
10164             if (isolatedUid == 0) {
10165                 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
10166                 while (true) {
10167                     if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
10168                             || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
10169                         mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
10170                     }
10171                     uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
10172                     mNextIsolatedProcessUid++;
10173                     if (mIsolatedProcesses.indexOfKey(uid) < 0) {
10174                         // No process for this uid, use it.
10175                         break;
10176                     }
10177                     stepsLeft--;
10178                     if (stepsLeft <= 0) {
10179                         return null;
10180                     }
10181                 }
10182             } else {
10183                 // Special case for startIsolatedProcess (internal only), where
10184                 // the uid of the isolated process is specified by the caller.
10185                 uid = isolatedUid;
10186             }
10187         }
10188         final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
10189         if (!mBooted && !mBooting
10190                 && userId == UserHandle.USER_OWNER
10191                 && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
10192             r.persistent = true;
10193         }
10194         addProcessNameLocked(r);
10195         return r;
10196     }
10197
10198     final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
10199             String abiOverride) {
10200         ProcessRecord app;
10201         if (!isolated) {
10202             app = getProcessRecordLocked(info.processName, info.uid, true);
10203         } else {
10204             app = null;
10205         }
10206
10207         if (app == null) {
10208             app = newProcessRecordLocked(info, null, isolated, 0);
10209             updateLruProcessLocked(app, false, null);
10210             updateOomAdjLocked();
10211         }
10212
10213         // This package really, really can not be stopped.
10214         try {
10215             AppGlobals.getPackageManager().setPackageStoppedState(
10216                     info.packageName, false, UserHandle.getUserId(app.uid));
10217         } catch (RemoteException e) {
10218         } catch (IllegalArgumentException e) {
10219             Slog.w(TAG, "Failed trying to unstop package "
10220                     + info.packageName + ": " + e);
10221         }
10222
10223         if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
10224             app.persistent = true;
10225             app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
10226         }
10227         if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
10228             mPersistentStartingProcesses.add(app);
10229             startProcessLocked(app, "added application", app.processName, abiOverride,
10230                     null /* entryPoint */, null /* entryPointArgs */);
10231         }
10232
10233         return app;
10234     }
10235
10236     public void unhandledBack() {
10237         enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
10238                 "unhandledBack()");
10239
10240         synchronized(this) {
10241             final long origId = Binder.clearCallingIdentity();
10242             try {
10243                 getFocusedStack().unhandledBackLocked();
10244             } finally {
10245                 Binder.restoreCallingIdentity(origId);
10246             }
10247         }
10248     }
10249
10250     public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
10251         enforceNotIsolatedCaller("openContentUri");
10252         final int userId = UserHandle.getCallingUserId();
10253         String name = uri.getAuthority();
10254         ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
10255         ParcelFileDescriptor pfd = null;
10256         if (cph != null) {
10257             // We record the binder invoker's uid in thread-local storage before
10258             // going to the content provider to open the file.  Later, in the code
10259             // that handles all permissions checks, we look for this uid and use
10260             // that rather than the Activity Manager's own uid.  The effect is that
10261             // we do the check against the caller's permissions even though it looks
10262             // to the content provider like the Activity Manager itself is making
10263             // the request.
10264             Binder token = new Binder();
10265             sCallerIdentity.set(new Identity(
10266                     token, Binder.getCallingPid(), Binder.getCallingUid()));
10267             try {
10268                 pfd = cph.provider.openFile(null, uri, "r", null, token);
10269             } catch (FileNotFoundException e) {
10270                 // do nothing; pfd will be returned null
10271             } finally {
10272                 // Ensure that whatever happens, we clean up the identity state
10273                 sCallerIdentity.remove();
10274                 // Ensure we're done with the provider.
10275                 removeContentProviderExternalUnchecked(name, null, userId);
10276             }
10277         } else {
10278             Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
10279         }
10280         return pfd;
10281     }
10282
10283     // Actually is sleeping or shutting down or whatever else in the future
10284     // is an inactive state.
10285     public boolean isSleepingOrShuttingDown() {
10286         return isSleeping() || mShuttingDown;
10287     }
10288
10289     public boolean isSleeping() {
10290         return mSleeping;
10291     }
10292
10293     void onWakefulnessChanged(int wakefulness) {
10294         synchronized(this) {
10295             mWakefulness = wakefulness;
10296             updateSleepIfNeededLocked();
10297         }
10298     }
10299
10300     void finishRunningVoiceLocked() {
10301         if (mRunningVoice != null) {
10302             mRunningVoice = null;
10303             mVoiceWakeLock.release();
10304             updateSleepIfNeededLocked();
10305         }
10306     }
10307
10308     void startTimeTrackingFocusedActivityLocked() {
10309         if (!mSleeping && mCurAppTimeTracker != null && mFocusedActivity != null) {
10310             mCurAppTimeTracker.start(mFocusedActivity.packageName);
10311         }
10312     }
10313
10314     void updateSleepIfNeededLocked() {
10315         if (mSleeping && !shouldSleepLocked()) {
10316             mSleeping = false;
10317             startTimeTrackingFocusedActivityLocked();
10318             mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
10319             mStackSupervisor.comeOutOfSleepIfNeededLocked();
10320             updateOomAdjLocked();
10321         } else if (!mSleeping && shouldSleepLocked()) {
10322             mSleeping = true;
10323             if (mCurAppTimeTracker != null) {
10324                 mCurAppTimeTracker.stop();
10325             }
10326             mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
10327             mStackSupervisor.goingToSleepLocked();
10328             updateOomAdjLocked();
10329
10330             // Initialize the wake times of all processes.
10331             checkExcessivePowerUsageLocked(false);
10332             mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
10333             Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
10334             mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
10335         }
10336     }
10337
10338     private boolean shouldSleepLocked() {
10339         // Resume applications while running a voice interactor.
10340         if (mRunningVoice != null) {
10341             return false;
10342         }
10343
10344         // TODO: Transform the lock screen state into a sleep token instead.
10345         switch (mWakefulness) {
10346             case PowerManagerInternal.WAKEFULNESS_AWAKE:
10347             case PowerManagerInternal.WAKEFULNESS_DREAMING:
10348             case PowerManagerInternal.WAKEFULNESS_DOZING:
10349                 // Pause applications whenever the lock screen is shown or any sleep
10350                 // tokens have been acquired.
10351                 return (mLockScreenShown != LOCK_SCREEN_HIDDEN || !mSleepTokens.isEmpty());
10352             case PowerManagerInternal.WAKEFULNESS_ASLEEP:
10353             default:
10354                 // If we're asleep then pause applications unconditionally.
10355                 return true;
10356         }
10357     }
10358
10359     /** Pokes the task persister. */
10360     void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
10361         if (task != null && task.stack != null && task.stack.isHomeStack()) {
10362             // Never persist the home stack.
10363             return;
10364         }
10365         mTaskPersister.wakeup(task, flush);
10366     }
10367
10368     /** Notifies all listeners when the task stack has changed. */
10369     void notifyTaskStackChangedLocked() {
10370         mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
10371         Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
10372         mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
10373     }
10374
10375     @Override
10376     public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
10377         mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
10378     }
10379
10380     @Override
10381     public boolean shutdown(int timeout) {
10382         if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
10383                 != PackageManager.PERMISSION_GRANTED) {
10384             throw new SecurityException("Requires permission "
10385                     + android.Manifest.permission.SHUTDOWN);
10386         }
10387
10388         boolean timedout = false;
10389
10390         synchronized(this) {
10391             mShuttingDown = true;
10392             updateEventDispatchingLocked();
10393             timedout = mStackSupervisor.shutdownLocked(timeout);
10394         }
10395
10396         mAppOpsService.shutdown();
10397         if (mUsageStatsService != null) {
10398             mUsageStatsService.prepareShutdown();
10399         }
10400         mBatteryStatsService.shutdown();
10401         synchronized (this) {
10402             mProcessStats.shutdownLocked();
10403             notifyTaskPersisterLocked(null, true);
10404         }
10405
10406         return timedout;
10407     }
10408
10409     public final void activitySlept(IBinder token) {
10410         if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
10411
10412         final long origId = Binder.clearCallingIdentity();
10413
10414         synchronized (this) {
10415             final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10416             if (r != null) {
10417                 mStackSupervisor.activitySleptLocked(r);
10418             }
10419         }
10420
10421         Binder.restoreCallingIdentity(origId);
10422     }
10423
10424     private String lockScreenShownToString() {
10425         switch (mLockScreenShown) {
10426             case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
10427             case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
10428             case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
10429             default: return "Unknown=" + mLockScreenShown;
10430         }
10431     }
10432
10433     void logLockScreen(String msg) {
10434         if (DEBUG_LOCKSCREEN) Slog.d(TAG_LOCKSCREEN, Debug.getCallers(2) + ":" + msg
10435                 + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
10436                 + PowerManagerInternal.wakefulnessToString(mWakefulness)
10437                 + " mSleeping=" + mSleeping);
10438     }
10439
10440     void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
10441         mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
10442         if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
10443             boolean wasRunningVoice = mRunningVoice != null;
10444             mRunningVoice = session;
10445             if (!wasRunningVoice) {
10446                 mVoiceWakeLock.acquire();
10447                 updateSleepIfNeededLocked();
10448             }
10449         }
10450     }
10451
10452     private void updateEventDispatchingLocked() {
10453         mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
10454     }
10455
10456     public void setLockScreenShown(boolean shown) {
10457         if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
10458                 != PackageManager.PERMISSION_GRANTED) {
10459             throw new SecurityException("Requires permission "
10460                     + android.Manifest.permission.DEVICE_POWER);
10461         }
10462
10463         synchronized(this) {
10464             long ident = Binder.clearCallingIdentity();
10465             try {
10466                 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
10467                 mLockScreenShown = shown ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
10468                 updateSleepIfNeededLocked();
10469             } finally {
10470                 Binder.restoreCallingIdentity(ident);
10471             }
10472         }
10473     }
10474
10475     @Override
10476     public void stopAppSwitches() {
10477         if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10478                 != PackageManager.PERMISSION_GRANTED) {
10479             throw new SecurityException("Requires permission "
10480                     + android.Manifest.permission.STOP_APP_SWITCHES);
10481         }
10482
10483         synchronized(this) {
10484             mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
10485                     + APP_SWITCH_DELAY_TIME;
10486             mDidAppSwitch = false;
10487             mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10488             Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10489             mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
10490         }
10491     }
10492
10493     public void resumeAppSwitches() {
10494         if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10495                 != PackageManager.PERMISSION_GRANTED) {
10496             throw new SecurityException("Requires permission "
10497                     + android.Manifest.permission.STOP_APP_SWITCHES);
10498         }
10499
10500         synchronized(this) {
10501             // Note that we don't execute any pending app switches... we will
10502             // let those wait until either the timeout, or the next start
10503             // activity request.
10504             mAppSwitchesAllowedTime = 0;
10505         }
10506     }
10507
10508     boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
10509             int callingPid, int callingUid, String name) {
10510         if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
10511             return true;
10512         }
10513
10514         int perm = checkComponentPermission(
10515                 android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
10516                 sourceUid, -1, true);
10517         if (perm == PackageManager.PERMISSION_GRANTED) {
10518             return true;
10519         }
10520
10521         // If the actual IPC caller is different from the logical source, then
10522         // also see if they are allowed to control app switches.
10523         if (callingUid != -1 && callingUid != sourceUid) {
10524             perm = checkComponentPermission(
10525                     android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
10526                     callingUid, -1, true);
10527             if (perm == PackageManager.PERMISSION_GRANTED) {
10528                 return true;
10529             }
10530         }
10531
10532         Slog.w(TAG, name + " request from " + sourceUid + " stopped");
10533         return false;
10534     }
10535
10536     public void setDebugApp(String packageName, boolean waitForDebugger,
10537             boolean persistent) {
10538         enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
10539                 "setDebugApp()");
10540
10541         long ident = Binder.clearCallingIdentity();
10542         try {
10543             // Note that this is not really thread safe if there are multiple
10544             // callers into it at the same time, but that's not a situation we
10545             // care about.
10546             if (persistent) {
10547                 final ContentResolver resolver = mContext.getContentResolver();
10548                 Settings.Global.putString(
10549                     resolver, Settings.Global.DEBUG_APP,
10550                     packageName);
10551                 Settings.Global.putInt(
10552                     resolver, Settings.Global.WAIT_FOR_DEBUGGER,
10553                     waitForDebugger ? 1 : 0);
10554             }
10555
10556             synchronized (this) {
10557                 if (!persistent) {
10558                     mOrigDebugApp = mDebugApp;
10559                     mOrigWaitForDebugger = mWaitForDebugger;
10560                 }
10561                 mDebugApp = packageName;
10562                 mWaitForDebugger = waitForDebugger;
10563                 mDebugTransient = !persistent;
10564                 if (packageName != null) {
10565                     forceStopPackageLocked(packageName, -1, false, false, true, true,
10566                             false, UserHandle.USER_ALL, "set debug app");
10567                 }
10568             }
10569         } finally {
10570             Binder.restoreCallingIdentity(ident);
10571         }
10572     }
10573
10574     void setOpenGlTraceApp(ApplicationInfo app, String processName) {
10575         synchronized (this) {
10576             boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10577             if (!isDebuggable) {
10578                 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10579                     throw new SecurityException("Process not debuggable: " + app.packageName);
10580                 }
10581             }
10582
10583             mOpenGlTraceApp = processName;
10584         }
10585     }
10586
10587     void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
10588         synchronized (this) {
10589             boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10590             if (!isDebuggable) {
10591                 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10592                     throw new SecurityException("Process not debuggable: " + app.packageName);
10593                 }
10594             }
10595             mProfileApp = processName;
10596             mProfileFile = profilerInfo.profileFile;
10597             if (mProfileFd != null) {
10598                 try {
10599                     mProfileFd.close();
10600                 } catch (IOException e) {
10601                 }
10602                 mProfileFd = null;
10603             }
10604             mProfileFd = profilerInfo.profileFd;
10605             mSamplingInterval = profilerInfo.samplingInterval;
10606             mAutoStopProfiler = profilerInfo.autoStopProfiler;
10607             mProfileType = 0;
10608         }
10609     }
10610
10611     @Override
10612     public void setAlwaysFinish(boolean enabled) {
10613         enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
10614                 "setAlwaysFinish()");
10615
10616         Settings.Global.putInt(
10617                 mContext.getContentResolver(),
10618                 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
10619
10620         synchronized (this) {
10621             mAlwaysFinishActivities = enabled;
10622         }
10623     }
10624
10625     @Override
10626     public void setActivityController(IActivityController controller) {
10627         enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10628                 "setActivityController()");
10629         synchronized (this) {
10630             mController = controller;
10631             Watchdog.getInstance().setActivityController(controller);
10632         }
10633     }
10634
10635     @Override
10636     public void setUserIsMonkey(boolean userIsMonkey) {
10637         synchronized (this) {
10638             synchronized (mPidsSelfLocked) {
10639                 final int callingPid = Binder.getCallingPid();
10640                 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
10641                 if (precessRecord == null) {
10642                     throw new SecurityException("Unknown process: " + callingPid);
10643                 }
10644                 if (precessRecord.instrumentationUiAutomationConnection  == null) {
10645                     throw new SecurityException("Only an instrumentation process "
10646                             + "with a UiAutomation can call setUserIsMonkey");
10647                 }
10648             }
10649             mUserIsMonkey = userIsMonkey;
10650         }
10651     }
10652
10653     @Override
10654     public boolean isUserAMonkey() {
10655         synchronized (this) {
10656             // If there is a controller also implies the user is a monkey.
10657             return (mUserIsMonkey || mController != null);
10658         }
10659     }
10660
10661     public void requestBugReport() {
10662         enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
10663         SystemProperties.set("ctl.start", "bugreport");
10664     }
10665
10666     public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
10667         return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
10668     }
10669
10670     public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
10671         if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
10672             return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
10673         }
10674         return KEY_DISPATCHING_TIMEOUT;
10675     }
10676
10677     @Override
10678     public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
10679         if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10680                 != PackageManager.PERMISSION_GRANTED) {
10681             throw new SecurityException("Requires permission "
10682                     + android.Manifest.permission.FILTER_EVENTS);
10683         }
10684         ProcessRecord proc;
10685         long timeout;
10686         synchronized (this) {
10687             synchronized (mPidsSelfLocked) {
10688                 proc = mPidsSelfLocked.get(pid);
10689             }
10690             timeout = getInputDispatchingTimeoutLocked(proc);
10691         }
10692
10693         if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
10694             return -1;
10695         }
10696
10697         return timeout;
10698     }
10699
10700     /**
10701      * Handle input dispatching timeouts.
10702      * Returns whether input dispatching should be aborted or not.
10703      */
10704     public boolean inputDispatchingTimedOut(final ProcessRecord proc,
10705             final ActivityRecord activity, final ActivityRecord parent,
10706             final boolean aboveSystem, String reason) {
10707         if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10708                 != PackageManager.PERMISSION_GRANTED) {
10709             throw new SecurityException("Requires permission "
10710                     + android.Manifest.permission.FILTER_EVENTS);
10711         }
10712
10713         final String annotation;
10714         if (reason == null) {
10715             annotation = "Input dispatching timed out";
10716         } else {
10717             annotation = "Input dispatching timed out (" + reason + ")";
10718         }
10719
10720         if (proc != null) {
10721             synchronized (this) {
10722                 if (proc.debugging) {
10723                     return false;
10724                 }
10725
10726                 if (mDidDexOpt) {
10727                     // Give more time since we were dexopting.
10728                     mDidDexOpt = false;
10729                     return false;
10730                 }
10731
10732                 if (proc.instrumentationClass != null) {
10733                     Bundle info = new Bundle();
10734                     info.putString("shortMsg", "keyDispatchingTimedOut");
10735                     info.putString("longMsg", annotation);
10736                     finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
10737                     return true;
10738                 }
10739             }
10740             mHandler.post(new Runnable() {
10741                 @Override
10742                 public void run() {
10743                     appNotResponding(proc, activity, parent, aboveSystem, annotation);
10744                 }
10745             });
10746         }
10747
10748         return true;
10749     }
10750
10751     @Override
10752     public Bundle getAssistContextExtras(int requestType) {
10753         PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
10754                 null, UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT);
10755         if (pae == null) {
10756             return null;
10757         }
10758         synchronized (pae) {
10759             while (!pae.haveResult) {
10760                 try {
10761                     pae.wait();
10762                 } catch (InterruptedException e) {
10763                 }
10764             }
10765         }
10766         synchronized (this) {
10767             buildAssistBundleLocked(pae, pae.result);
10768             mPendingAssistExtras.remove(pae);
10769             mUiHandler.removeCallbacks(pae);
10770         }
10771         return pae.extras;
10772     }
10773
10774     @Override
10775     public boolean isAssistDataAllowedOnCurrentActivity() {
10776         int userId = mCurrentUserId;
10777         synchronized (this) {
10778             ActivityRecord activity = getFocusedStack().topActivity();
10779             if (activity == null) {
10780                 return false;
10781             }
10782             userId = activity.userId;
10783         }
10784         DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
10785                 Context.DEVICE_POLICY_SERVICE);
10786         return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
10787     }
10788
10789     @Override
10790     public boolean showAssistFromActivity(IBinder token, Bundle args) {
10791         long ident = Binder.clearCallingIdentity();
10792         try {
10793             synchronized (this) {
10794                 ActivityRecord caller = ActivityRecord.forTokenLocked(token);
10795                 ActivityRecord top = getFocusedStack().topActivity();
10796                 if (top != caller) {
10797                     Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
10798                             + " is not current top " + top);
10799                     return false;
10800                 }
10801                 if (!top.nowVisible) {
10802                     Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
10803                             + " is not visible");
10804                     return false;
10805                 }
10806             }
10807             AssistUtils utils = new AssistUtils(mContext);
10808             return utils.showSessionForActiveService(args,
10809                     VoiceInteractionSession.SHOW_SOURCE_APPLICATION, null, token);
10810         } finally {
10811             Binder.restoreCallingIdentity(ident);
10812         }
10813     }
10814
10815     @Override
10816     public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
10817             IBinder activityToken) {
10818         return enqueueAssistContext(requestType, null, null, receiver, activityToken,
10819                 UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_LONG_TIMEOUT) != null;
10820     }
10821
10822     private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
10823             IResultReceiver receiver, IBinder activityToken, int userHandle, Bundle args,
10824             long timeout) {
10825         enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
10826                 "enqueueAssistContext()");
10827         synchronized (this) {
10828             ActivityRecord activity = getFocusedStack().topActivity();
10829             if (activity == null) {
10830                 Slog.w(TAG, "getAssistContextExtras failed: no top activity");
10831                 return null;
10832             }
10833             if (activity.app == null || activity.app.thread == null) {
10834                 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
10835                 return null;
10836             }
10837             if (activityToken != null) {
10838                 ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
10839                 if (activity != caller) {
10840                     Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
10841                             + " is not current top " + activity);
10842                     return null;
10843                 }
10844             }
10845             PendingAssistExtras pae;
10846             Bundle extras = new Bundle();
10847             if (args != null) {
10848                 extras.putAll(args);
10849             }
10850             extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
10851             extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
10852             pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, userHandle);
10853             try {
10854                 activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
10855                         requestType);
10856                 mPendingAssistExtras.add(pae);
10857                 mUiHandler.postDelayed(pae, timeout);
10858             } catch (RemoteException e) {
10859                 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
10860                 return null;
10861             }
10862             return pae;
10863         }
10864     }
10865
10866     void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
10867         IResultReceiver receiver;
10868         synchronized (this) {
10869             mPendingAssistExtras.remove(pae);
10870             receiver = pae.receiver;
10871         }
10872         if (receiver != null) {
10873             // Caller wants result sent back to them.
10874             try {
10875                 pae.receiver.send(0, null);
10876             } catch (RemoteException e) {
10877             }
10878         }
10879     }
10880
10881     private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
10882         if (result != null) {
10883             pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
10884         }
10885         if (pae.hint != null) {
10886             pae.extras.putBoolean(pae.hint, true);
10887         }
10888     }
10889
10890     public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
10891             AssistContent content, Uri referrer) {
10892         PendingAssistExtras pae = (PendingAssistExtras)token;
10893         synchronized (pae) {
10894             pae.result = extras;
10895             pae.structure = structure;
10896             pae.content = content;
10897             if (referrer != null) {
10898                 pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
10899             }
10900             pae.haveResult = true;
10901             pae.notifyAll();
10902             if (pae.intent == null && pae.receiver == null) {
10903                 // Caller is just waiting for the result.
10904                 return;
10905             }
10906         }
10907
10908         // We are now ready to launch the assist activity.
10909         IResultReceiver sendReceiver = null;
10910         Bundle sendBundle = null;
10911         synchronized (this) {
10912             buildAssistBundleLocked(pae, extras);
10913             boolean exists = mPendingAssistExtras.remove(pae);
10914             mUiHandler.removeCallbacks(pae);
10915             if (!exists) {
10916                 // Timed out.
10917                 return;
10918             }
10919             if ((sendReceiver=pae.receiver) != null) {
10920                 // Caller wants result sent back to them.
10921                 sendBundle = new Bundle();
10922                 sendBundle.putBundle("data", pae.extras);
10923                 sendBundle.putParcelable("structure", pae.structure);
10924                 sendBundle.putParcelable("content", pae.content);
10925             }
10926         }
10927         if (sendReceiver != null) {
10928             try {
10929                 sendReceiver.send(0, sendBundle);
10930             } catch (RemoteException e) {
10931             }
10932             return;
10933         }
10934
10935         long ident = Binder.clearCallingIdentity();
10936         try {
10937             pae.intent.replaceExtras(pae.extras);
10938             pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10939                     | Intent.FLAG_ACTIVITY_SINGLE_TOP
10940                     | Intent.FLAG_ACTIVITY_CLEAR_TOP);
10941             closeSystemDialogs("assist");
10942             try {
10943                 mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
10944             } catch (ActivityNotFoundException e) {
10945                 Slog.w(TAG, "No activity to handle assist action.", e);
10946             }
10947         } finally {
10948             Binder.restoreCallingIdentity(ident);
10949         }
10950     }
10951
10952     public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
10953             Bundle args) {
10954         return enqueueAssistContext(requestType, intent, hint, null, null, userHandle, args,
10955                 PENDING_ASSIST_EXTRAS_TIMEOUT) != null;
10956     }
10957
10958     public void registerProcessObserver(IProcessObserver observer) {
10959         enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10960                 "registerProcessObserver()");
10961         synchronized (this) {
10962             mProcessObservers.register(observer);
10963         }
10964     }
10965
10966     @Override
10967     public void unregisterProcessObserver(IProcessObserver observer) {
10968         synchronized (this) {
10969             mProcessObservers.unregister(observer);
10970         }
10971     }
10972
10973     public void registerUidObserver(IUidObserver observer) {
10974         enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10975                 "registerUidObserver()");
10976         synchronized (this) {
10977             mUidObservers.register(observer);
10978         }
10979     }
10980
10981     @Override
10982     public void unregisterUidObserver(IUidObserver observer) {
10983         synchronized (this) {
10984             mUidObservers.unregister(observer);
10985         }
10986     }
10987
10988     @Override
10989     public boolean convertFromTranslucent(IBinder token) {
10990         final long origId = Binder.clearCallingIdentity();
10991         try {
10992             synchronized (this) {
10993                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10994                 if (r == null) {
10995                     return false;
10996                 }
10997                 final boolean translucentChanged = r.changeWindowTranslucency(true);
10998                 if (translucentChanged) {
10999                     r.task.stack.releaseBackgroundResources(r);
11000                     mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
11001                 }
11002                 mWindowManager.setAppFullscreen(token, true);
11003                 return translucentChanged;
11004             }
11005         } finally {
11006             Binder.restoreCallingIdentity(origId);
11007         }
11008     }
11009
11010     @Override
11011     public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
11012         final long origId = Binder.clearCallingIdentity();
11013         try {
11014             synchronized (this) {
11015                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11016                 if (r == null) {
11017                     return false;
11018                 }
11019                 int index = r.task.mActivities.lastIndexOf(r);
11020                 if (index > 0) {
11021                     ActivityRecord under = r.task.mActivities.get(index - 1);
11022                     under.returningOptions = options;
11023                 }
11024                 final boolean translucentChanged = r.changeWindowTranslucency(false);
11025                 if (translucentChanged) {
11026                     r.task.stack.convertActivityToTranslucent(r);
11027                 }
11028                 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
11029                 mWindowManager.setAppFullscreen(token, false);
11030                 return translucentChanged;
11031             }
11032         } finally {
11033             Binder.restoreCallingIdentity(origId);
11034         }
11035     }
11036
11037     @Override
11038     public boolean requestVisibleBehind(IBinder token, boolean visible) {
11039         final long origId = Binder.clearCallingIdentity();
11040         try {
11041             synchronized (this) {
11042                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11043                 if (r != null) {
11044                     return mStackSupervisor.requestVisibleBehindLocked(r, visible);
11045                 }
11046             }
11047             return false;
11048         } finally {
11049             Binder.restoreCallingIdentity(origId);
11050         }
11051     }
11052
11053     @Override
11054     public boolean isBackgroundVisibleBehind(IBinder token) {
11055         final long origId = Binder.clearCallingIdentity();
11056         try {
11057             synchronized (this) {
11058                 final ActivityStack stack = ActivityRecord.getStackLocked(token);
11059                 final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
11060                 if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
11061                         "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
11062                 return visible;
11063             }
11064         } finally {
11065             Binder.restoreCallingIdentity(origId);
11066         }
11067     }
11068
11069     @Override
11070     public ActivityOptions getActivityOptions(IBinder token) {
11071         final long origId = Binder.clearCallingIdentity();
11072         try {
11073             synchronized (this) {
11074                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11075                 if (r != null) {
11076                     final ActivityOptions activityOptions = r.pendingOptions;
11077                     r.pendingOptions = null;
11078                     return activityOptions;
11079                 }
11080                 return null;
11081             }
11082         } finally {
11083             Binder.restoreCallingIdentity(origId);
11084         }
11085     }
11086
11087     @Override
11088     public void setImmersive(IBinder token, boolean immersive) {
11089         synchronized(this) {
11090             final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11091             if (r == null) {
11092                 throw new IllegalArgumentException();
11093             }
11094             r.immersive = immersive;
11095
11096             // update associated state if we're frontmost
11097             if (r == mFocusedActivity) {
11098                 if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
11099                 applyUpdateLockStateLocked(r);
11100             }
11101         }
11102     }
11103
11104     @Override
11105     public boolean isImmersive(IBinder token) {
11106         synchronized (this) {
11107             ActivityRecord r = ActivityRecord.isInStackLocked(token);
11108             if (r == null) {
11109                 throw new IllegalArgumentException();
11110             }
11111             return r.immersive;
11112         }
11113     }
11114
11115     public boolean isTopActivityImmersive() {
11116         enforceNotIsolatedCaller("startActivity");
11117         synchronized (this) {
11118             ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
11119             return (r != null) ? r.immersive : false;
11120         }
11121     }
11122
11123     @Override
11124     public boolean isTopOfTask(IBinder token) {
11125         synchronized (this) {
11126             ActivityRecord r = ActivityRecord.isInStackLocked(token);
11127             if (r == null) {
11128                 throw new IllegalArgumentException();
11129             }
11130             return r.task.getTopActivity() == r;
11131         }
11132     }
11133
11134     public final void enterSafeMode() {
11135         synchronized(this) {
11136             // It only makes sense to do this before the system is ready
11137             // and started launching other packages.
11138             if (!mSystemReady) {
11139                 try {
11140                     AppGlobals.getPackageManager().enterSafeMode();
11141                 } catch (RemoteException e) {
11142                 }
11143             }
11144
11145             mSafeMode = true;
11146         }
11147     }
11148
11149     public final void showSafeModeOverlay() {
11150         View v = LayoutInflater.from(mContext).inflate(
11151                 com.android.internal.R.layout.safe_mode, null);
11152         WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
11153         lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
11154         lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
11155         lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
11156         lp.gravity = Gravity.BOTTOM | Gravity.START;
11157         lp.format = v.getBackground().getOpacity();
11158         lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
11159                 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
11160         lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
11161         ((WindowManager)mContext.getSystemService(
11162                 Context.WINDOW_SERVICE)).addView(v, lp);
11163     }
11164
11165     public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
11166         if (!(sender instanceof PendingIntentRecord)) {
11167             return;
11168         }
11169         final PendingIntentRecord rec = (PendingIntentRecord)sender;
11170         final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11171         synchronized (stats) {
11172             if (mBatteryStatsService.isOnBattery()) {
11173                 mBatteryStatsService.enforceCallingPermission();
11174                 int MY_UID = Binder.getCallingUid();
11175                 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
11176                 BatteryStatsImpl.Uid.Pkg pkg =
11177                     stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
11178                             sourcePkg != null ? sourcePkg : rec.key.packageName);
11179                 pkg.noteWakeupAlarmLocked(tag);
11180             }
11181         }
11182     }
11183
11184     public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
11185         if (!(sender instanceof PendingIntentRecord)) {
11186             return;
11187         }
11188         final PendingIntentRecord rec = (PendingIntentRecord)sender;
11189         final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11190         synchronized (stats) {
11191             mBatteryStatsService.enforceCallingPermission();
11192             int MY_UID = Binder.getCallingUid();
11193             int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
11194             mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
11195         }
11196     }
11197
11198     public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
11199         if (!(sender instanceof PendingIntentRecord)) {
11200             return;
11201         }
11202         final PendingIntentRecord rec = (PendingIntentRecord)sender;
11203         final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11204         synchronized (stats) {
11205             mBatteryStatsService.enforceCallingPermission();
11206             int MY_UID = Binder.getCallingUid();
11207             int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
11208             mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
11209         }
11210     }
11211
11212     public boolean killPids(int[] pids, String pReason, boolean secure) {
11213         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
11214             throw new SecurityException("killPids only available to the system");
11215         }
11216         String reason = (pReason == null) ? "Unknown" : pReason;
11217         // XXX Note: don't acquire main activity lock here, because the window
11218         // manager calls in with its locks held.
11219
11220         boolean killed = false;
11221         synchronized (mPidsSelfLocked) {
11222             int[] types = new int[pids.length];
11223             int worstType = 0;
11224             for (int i=0; i<pids.length; i++) {
11225                 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
11226                 if (proc != null) {
11227                     int type = proc.setAdj;
11228                     types[i] = type;
11229                     if (type > worstType) {
11230                         worstType = type;
11231                     }
11232                 }
11233             }
11234
11235             // If the worst oom_adj is somewhere in the cached proc LRU range,
11236             // then constrain it so we will kill all cached procs.
11237             if (worstType < ProcessList.CACHED_APP_MAX_ADJ
11238                     && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
11239                 worstType = ProcessList.CACHED_APP_MIN_ADJ;
11240             }
11241
11242             // If this is not a secure call, don't let it kill processes that
11243             // are important.
11244             if (!secure && worstType < ProcessList.SERVICE_ADJ) {
11245                 worstType = ProcessList.SERVICE_ADJ;
11246             }
11247
11248             Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
11249             for (int i=0; i<pids.length; i++) {
11250                 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
11251                 if (proc == null) {
11252                     continue;
11253                 }
11254                 int adj = proc.setAdj;
11255                 if (adj >= worstType && !proc.killedByAm) {
11256                     proc.kill(reason, true);
11257                     killed = true;
11258                 }
11259             }
11260         }
11261         return killed;
11262     }
11263
11264     @Override
11265     public void killUid(int appId, int userId, String reason) {
11266         enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
11267         synchronized (this) {
11268             final long identity = Binder.clearCallingIdentity();
11269             try {
11270                 killPackageProcessesLocked(null, appId, userId,
11271                         ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
11272                         reason != null ? reason : "kill uid");
11273             } finally {
11274                 Binder.restoreCallingIdentity(identity);
11275             }
11276         }
11277     }
11278
11279     @Override
11280     public boolean killProcessesBelowForeground(String reason) {
11281         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
11282             throw new SecurityException("killProcessesBelowForeground() only available to system");
11283         }
11284
11285         return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
11286     }
11287
11288     private boolean killProcessesBelowAdj(int belowAdj, String reason) {
11289         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
11290             throw new SecurityException("killProcessesBelowAdj() only available to system");
11291         }
11292
11293         boolean killed = false;
11294         synchronized (mPidsSelfLocked) {
11295             final int size = mPidsSelfLocked.size();
11296             for (int i = 0; i < size; i++) {
11297                 final int pid = mPidsSelfLocked.keyAt(i);
11298                 final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
11299                 if (proc == null) continue;
11300
11301                 final int adj = proc.setAdj;
11302                 if (adj > belowAdj && !proc.killedByAm) {
11303                     proc.kill(reason, true);
11304                     killed = true;
11305                 }
11306             }
11307         }
11308         return killed;
11309     }
11310
11311     @Override
11312     public void hang(final IBinder who, boolean allowRestart) {
11313         if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
11314                 != PackageManager.PERMISSION_GRANTED) {
11315             throw new SecurityException("Requires permission "
11316                     + android.Manifest.permission.SET_ACTIVITY_WATCHER);
11317         }
11318
11319         final IBinder.DeathRecipient death = new DeathRecipient() {
11320             @Override
11321             public void binderDied() {
11322                 synchronized (this) {
11323                     notifyAll();
11324                 }
11325             }
11326         };
11327
11328         try {
11329             who.linkToDeath(death, 0);
11330         } catch (RemoteException e) {
11331             Slog.w(TAG, "hang: given caller IBinder is already dead.");
11332             return;
11333         }
11334
11335         synchronized (this) {
11336             Watchdog.getInstance().setAllowRestart(allowRestart);
11337             Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
11338             synchronized (death) {
11339                 while (who.isBinderAlive()) {
11340                     try {
11341                         death.wait();
11342                     } catch (InterruptedException e) {
11343                     }
11344                 }
11345             }
11346             Watchdog.getInstance().setAllowRestart(true);
11347         }
11348     }
11349
11350     @Override
11351     public void restart() {
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         Log.i(TAG, "Sending shutdown broadcast...");
11359
11360         BroadcastReceiver br = new BroadcastReceiver() {
11361             @Override public void onReceive(Context context, Intent intent) {
11362                 // Now the broadcast is done, finish up the low-level shutdown.
11363                 Log.i(TAG, "Shutting down activity manager...");
11364                 shutdown(10000);
11365                 Log.i(TAG, "Shutdown complete, restarting!");
11366                 Process.killProcess(Process.myPid());
11367                 System.exit(10);
11368             }
11369         };
11370
11371         // First send the high-level shut down broadcast.
11372         Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
11373         intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
11374         intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
11375         /* For now we are not doing a clean shutdown, because things seem to get unhappy.
11376         mContext.sendOrderedBroadcastAsUser(intent,
11377                 UserHandle.ALL, null, br, mHandler, 0, null, null);
11378         */
11379         br.onReceive(mContext, intent);
11380     }
11381
11382     private long getLowRamTimeSinceIdle(long now) {
11383         return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
11384     }
11385
11386     @Override
11387     public void performIdleMaintenance() {
11388         if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
11389                 != PackageManager.PERMISSION_GRANTED) {
11390             throw new SecurityException("Requires permission "
11391                     + android.Manifest.permission.SET_ACTIVITY_WATCHER);
11392         }
11393
11394         synchronized (this) {
11395             final long now = SystemClock.uptimeMillis();
11396             final long timeSinceLastIdle = now - mLastIdleTime;
11397             final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
11398             mLastIdleTime = now;
11399             mLowRamTimeSinceLastIdle = 0;
11400             if (mLowRamStartTime != 0) {
11401                 mLowRamStartTime = now;
11402             }
11403
11404             StringBuilder sb = new StringBuilder(128);
11405             sb.append("Idle maintenance over ");
11406             TimeUtils.formatDuration(timeSinceLastIdle, sb);
11407             sb.append(" low RAM for ");
11408             TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
11409             Slog.i(TAG, sb.toString());
11410
11411             // If at least 1/3 of our time since the last idle period has been spent
11412             // with RAM low, then we want to kill processes.
11413             boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
11414
11415             for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
11416                 ProcessRecord proc = mLruProcesses.get(i);
11417                 if (proc.notCachedSinceIdle) {
11418                     if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
11419                             && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
11420                             && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
11421                         if (doKilling && proc.initialIdlePss != 0
11422                                 && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
11423                             sb = new StringBuilder(128);
11424                             sb.append("Kill");
11425                             sb.append(proc.processName);
11426                             sb.append(" in idle maint: pss=");
11427                             sb.append(proc.lastPss);
11428                             sb.append(", initialPss=");
11429                             sb.append(proc.initialIdlePss);
11430                             sb.append(", period=");
11431                             TimeUtils.formatDuration(timeSinceLastIdle, sb);
11432                             sb.append(", lowRamPeriod=");
11433                             TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
11434                             Slog.wtfQuiet(TAG, sb.toString());
11435                             proc.kill("idle maint (pss " + proc.lastPss
11436                                     + " from " + proc.initialIdlePss + ")", true);
11437                         }
11438                     }
11439                 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
11440                     proc.notCachedSinceIdle = true;
11441                     proc.initialIdlePss = 0;
11442                     proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
11443                             mTestPssMode, isSleeping(), now);
11444                 }
11445             }
11446
11447             mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
11448             mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
11449         }
11450     }
11451
11452     private void retrieveSettings() {
11453         final ContentResolver resolver = mContext.getContentResolver();
11454         String debugApp = Settings.Global.getString(
11455             resolver, Settings.Global.DEBUG_APP);
11456         boolean waitForDebugger = Settings.Global.getInt(
11457             resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
11458         boolean alwaysFinishActivities = Settings.Global.getInt(
11459             resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
11460         boolean forceRtl = Settings.Global.getInt(
11461                 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
11462         // Transfer any global setting for forcing RTL layout, into a System Property
11463         SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
11464
11465         Configuration configuration = new Configuration();
11466         Settings.System.getConfiguration(resolver, configuration);
11467         if (forceRtl) {
11468             // This will take care of setting the correct layout direction flags
11469             configuration.setLayoutDirection(configuration.locale);
11470         }
11471
11472         synchronized (this) {
11473             mDebugApp = mOrigDebugApp = debugApp;
11474             mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
11475             mAlwaysFinishActivities = alwaysFinishActivities;
11476             // This happens before any activities are started, so we can
11477             // change mConfiguration in-place.
11478             updateConfigurationLocked(configuration, null, false, true);
11479             if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
11480                     "Initial config: " + mConfiguration);
11481         }
11482     }
11483
11484     /** Loads resources after the current configuration has been set. */
11485     private void loadResourcesOnSystemReady() {
11486         final Resources res = mContext.getResources();
11487         mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
11488         mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
11489         mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
11490     }
11491
11492     public boolean testIsSystemReady() {
11493         // no need to synchronize(this) just to read & return the value
11494         return mSystemReady;
11495     }
11496
11497     private static File getCalledPreBootReceiversFile() {
11498         File dataDir = Environment.getDataDirectory();
11499         File systemDir = new File(dataDir, "system");
11500         File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
11501         return fname;
11502     }
11503
11504     private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
11505         ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
11506         File file = getCalledPreBootReceiversFile();
11507         FileInputStream fis = null;
11508         try {
11509             fis = new FileInputStream(file);
11510             DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
11511             int fvers = dis.readInt();
11512             if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
11513                 String vers = dis.readUTF();
11514                 String codename = dis.readUTF();
11515                 String build = dis.readUTF();
11516                 if (android.os.Build.VERSION.RELEASE.equals(vers)
11517                         && android.os.Build.VERSION.CODENAME.equals(codename)
11518                         && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
11519                     int num = dis.readInt();
11520                     while (num > 0) {
11521                         num--;
11522                         String pkg = dis.readUTF();
11523                         String cls = dis.readUTF();
11524                         lastDoneReceivers.add(new ComponentName(pkg, cls));
11525                     }
11526                 }
11527             }
11528         } catch (FileNotFoundException e) {
11529         } catch (IOException e) {
11530             Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
11531         } finally {
11532             if (fis != null) {
11533                 try {
11534                     fis.close();
11535                 } catch (IOException e) {
11536                 }
11537             }
11538         }
11539         return lastDoneReceivers;
11540     }
11541
11542     private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
11543         File file = getCalledPreBootReceiversFile();
11544         FileOutputStream fos = null;
11545         DataOutputStream dos = null;
11546         try {
11547             fos = new FileOutputStream(file);
11548             dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
11549             dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
11550             dos.writeUTF(android.os.Build.VERSION.RELEASE);
11551             dos.writeUTF(android.os.Build.VERSION.CODENAME);
11552             dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
11553             dos.writeInt(list.size());
11554             for (int i=0; i<list.size(); i++) {
11555                 dos.writeUTF(list.get(i).getPackageName());
11556                 dos.writeUTF(list.get(i).getClassName());
11557             }
11558         } catch (IOException e) {
11559             Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
11560             file.delete();
11561         } finally {
11562             FileUtils.sync(fos);
11563             if (dos != null) {
11564                 try {
11565                     dos.close();
11566                 } catch (IOException e) {
11567                     // TODO Auto-generated catch block
11568                     e.printStackTrace();
11569                 }
11570             }
11571         }
11572     }
11573
11574     final class PreBootContinuation extends IIntentReceiver.Stub {
11575         final Intent intent;
11576         final Runnable onFinishCallback;
11577         final ArrayList<ComponentName> doneReceivers;
11578         final List<ResolveInfo> ris;
11579         final int[] users;
11580         int lastRi = -1;
11581         int curRi = 0;
11582         int curUser = 0;
11583
11584         PreBootContinuation(Intent _intent, Runnable _onFinishCallback,
11585                 ArrayList<ComponentName> _doneReceivers, List<ResolveInfo> _ris, int[] _users) {
11586             intent = _intent;
11587             onFinishCallback = _onFinishCallback;
11588             doneReceivers = _doneReceivers;
11589             ris = _ris;
11590             users = _users;
11591         }
11592
11593         void go() {
11594             if (lastRi != curRi) {
11595                 ActivityInfo ai = ris.get(curRi).activityInfo;
11596                 ComponentName comp = new ComponentName(ai.packageName, ai.name);
11597                 intent.setComponent(comp);
11598                 doneReceivers.add(comp);
11599                 lastRi = curRi;
11600                 CharSequence label = ai.loadLabel(mContext.getPackageManager());
11601                 showBootMessage(mContext.getString(R.string.android_preparing_apk, label), false);
11602             }
11603             Slog.i(TAG, "Pre-boot of " + intent.getComponent().toShortString()
11604                     + " for user " + users[curUser]);
11605             EventLogTags.writeAmPreBoot(users[curUser], intent.getComponent().getPackageName());
11606             broadcastIntentLocked(null, null, intent, null, this,
11607                     0, null, null, null, AppOpsManager.OP_NONE,
11608                     null, true, false, MY_PID, Process.SYSTEM_UID, users[curUser]);
11609         }
11610
11611         public void performReceive(Intent intent, int resultCode,
11612                 String data, Bundle extras, boolean ordered,
11613                 boolean sticky, int sendingUser) {
11614             curUser++;
11615             if (curUser >= users.length) {
11616                 curUser = 0;
11617                 curRi++;
11618                 if (curRi >= ris.size()) {
11619                     // All done sending broadcasts!
11620                     if (onFinishCallback != null) {
11621                         // The raw IIntentReceiver interface is called
11622                         // with the AM lock held, so redispatch to
11623                         // execute our code without the lock.
11624                         mHandler.post(onFinishCallback);
11625                     }
11626                     return;
11627                 }
11628             }
11629             go();
11630         }
11631     }
11632
11633     private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
11634             ArrayList<ComponentName> doneReceivers, int userId) {
11635         Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
11636         List<ResolveInfo> ris = null;
11637         try {
11638             ris = AppGlobals.getPackageManager().queryIntentReceivers(
11639                     intent, null, 0, userId);
11640         } catch (RemoteException e) {
11641         }
11642         if (ris == null) {
11643             return false;
11644         }
11645         for (int i=ris.size()-1; i>=0; i--) {
11646             if ((ris.get(i).activityInfo.applicationInfo.flags
11647                     &ApplicationInfo.FLAG_SYSTEM) == 0) {
11648                 ris.remove(i);
11649             }
11650         }
11651         intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
11652
11653         // For User 0, load the version number. When delivering to a new user, deliver
11654         // to all receivers.
11655         if (userId == UserHandle.USER_OWNER) {
11656             ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
11657             for (int i=0; i<ris.size(); i++) {
11658                 ActivityInfo ai = ris.get(i).activityInfo;
11659                 ComponentName comp = new ComponentName(ai.packageName, ai.name);
11660                 if (lastDoneReceivers.contains(comp)) {
11661                     // We already did the pre boot receiver for this app with the current
11662                     // platform version, so don't do it again...
11663                     ris.remove(i);
11664                     i--;
11665                     // ...however, do keep it as one that has been done, so we don't
11666                     // forget about it when rewriting the file of last done receivers.
11667                     doneReceivers.add(comp);
11668                 }
11669             }
11670         }
11671
11672         if (ris.size() <= 0) {
11673             return false;
11674         }
11675
11676         // If primary user, send broadcast to all available users, else just to userId
11677         final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
11678                 : new int[] { userId };
11679         if (users.length <= 0) {
11680             return false;
11681         }
11682
11683         PreBootContinuation cont = new PreBootContinuation(intent, onFinishCallback, doneReceivers,
11684                 ris, users);
11685         cont.go();
11686         return true;
11687     }
11688
11689     public void systemReady(final Runnable goingCallback) {
11690         synchronized(this) {
11691             if (mSystemReady) {
11692                 // If we're done calling all the receivers, run the next "boot phase" passed in
11693                 // by the SystemServer
11694                 if (goingCallback != null) {
11695                     goingCallback.run();
11696                 }
11697                 return;
11698             }
11699
11700             mLocalDeviceIdleController
11701                     = LocalServices.getService(DeviceIdleController.LocalService.class);
11702
11703             // Make sure we have the current profile info, since it is needed for
11704             // security checks.
11705             updateCurrentProfileIdsLocked();
11706
11707             mRecentTasks.clear();
11708             mRecentTasks.addAll(mTaskPersister.restoreTasksLocked());
11709             mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
11710             mTaskPersister.startPersisting();
11711
11712             // Check to see if there are any update receivers to run.
11713             if (!mDidUpdate) {
11714                 if (mWaitingUpdate) {
11715                     return;
11716                 }
11717                 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
11718                 mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
11719                     public void run() {
11720                         synchronized (ActivityManagerService.this) {
11721                             mDidUpdate = true;
11722                         }
11723                         showBootMessage(mContext.getText(
11724                                 R.string.android_upgrading_complete),
11725                                 false);
11726                         writeLastDonePreBootReceivers(doneReceivers);
11727                         systemReady(goingCallback);
11728                     }
11729                 }, doneReceivers, UserHandle.USER_OWNER);
11730
11731                 if (mWaitingUpdate) {
11732                     return;
11733                 }
11734                 mDidUpdate = true;
11735             }
11736
11737             mAppOpsService.systemReady();
11738             mSystemReady = true;
11739         }
11740
11741         ArrayList<ProcessRecord> procsToKill = null;
11742         synchronized(mPidsSelfLocked) {
11743             for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
11744                 ProcessRecord proc = mPidsSelfLocked.valueAt(i);
11745                 if (!isAllowedWhileBooting(proc.info)){
11746                     if (procsToKill == null) {
11747                         procsToKill = new ArrayList<ProcessRecord>();
11748                     }
11749                     procsToKill.add(proc);
11750                 }
11751             }
11752         }
11753
11754         synchronized(this) {
11755             if (procsToKill != null) {
11756                 for (int i=procsToKill.size()-1; i>=0; i--) {
11757                     ProcessRecord proc = procsToKill.get(i);
11758                     Slog.i(TAG, "Removing system update proc: " + proc);
11759                     removeProcessLocked(proc, true, false, "system update done");
11760                 }
11761             }
11762
11763             // Now that we have cleaned up any update processes, we
11764             // are ready to start launching real processes and know that
11765             // we won't trample on them any more.
11766             mProcessesReady = true;
11767         }
11768
11769         Slog.i(TAG, "System now ready");
11770         EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
11771             SystemClock.uptimeMillis());
11772
11773         synchronized(this) {
11774             // Make sure we have no pre-ready processes sitting around.
11775
11776             if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11777                 ResolveInfo ri = mContext.getPackageManager()
11778                         .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
11779                                 STOCK_PM_FLAGS);
11780                 CharSequence errorMsg = null;
11781                 if (ri != null) {
11782                     ActivityInfo ai = ri.activityInfo;
11783                     ApplicationInfo app = ai.applicationInfo;
11784                     if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
11785                         mTopAction = Intent.ACTION_FACTORY_TEST;
11786                         mTopData = null;
11787                         mTopComponent = new ComponentName(app.packageName,
11788                                 ai.name);
11789                     } else {
11790                         errorMsg = mContext.getResources().getText(
11791                                 com.android.internal.R.string.factorytest_not_system);
11792                     }
11793                 } else {
11794                     errorMsg = mContext.getResources().getText(
11795                             com.android.internal.R.string.factorytest_no_action);
11796                 }
11797                 if (errorMsg != null) {
11798                     mTopAction = null;
11799                     mTopData = null;
11800                     mTopComponent = null;
11801                     Message msg = Message.obtain();
11802                     msg.what = SHOW_FACTORY_ERROR_MSG;
11803                     msg.getData().putCharSequence("msg", errorMsg);
11804                     mUiHandler.sendMessage(msg);
11805                 }
11806             }
11807         }
11808
11809         retrieveSettings();
11810         loadResourcesOnSystemReady();
11811
11812         synchronized (this) {
11813             readGrantedUriPermissionsLocked();
11814         }
11815
11816         if (goingCallback != null) goingCallback.run();
11817
11818         mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
11819                 Integer.toString(mCurrentUserId), mCurrentUserId);
11820         mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
11821                 Integer.toString(mCurrentUserId), mCurrentUserId);
11822         mSystemServiceManager.startUser(mCurrentUserId);
11823
11824         synchronized (this) {
11825             if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11826                 try {
11827                     List apps = AppGlobals.getPackageManager().
11828                         getPersistentApplications(STOCK_PM_FLAGS);
11829                     if (apps != null) {
11830                         int N = apps.size();
11831                         int i;
11832                         for (i=0; i<N; i++) {
11833                             ApplicationInfo info
11834                                 = (ApplicationInfo)apps.get(i);
11835                             if (info != null &&
11836                                     !info.packageName.equals("android")) {
11837                                 addAppLocked(info, false, null /* ABI override */);
11838                             }
11839                         }
11840                     }
11841                 } catch (RemoteException ex) {
11842                     // pm is in same process, this will never happen.
11843                 }
11844             }
11845
11846             // Start up initial activity.
11847             mBooting = true;
11848             startHomeActivityLocked(mCurrentUserId, "systemReady");
11849
11850             try {
11851                 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
11852                     Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
11853                             + " data partition or your device will be unstable.");
11854                     mUiHandler.obtainMessage(SHOW_UID_ERROR_MSG).sendToTarget();
11855                 }
11856             } catch (RemoteException e) {
11857             }
11858
11859             if (!Build.isBuildConsistent()) {
11860                 Slog.e(TAG, "Build fingerprint is not consistent, warning user");
11861                 mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_MSG).sendToTarget();
11862             }
11863
11864             long ident = Binder.clearCallingIdentity();
11865             try {
11866                 Intent intent = new Intent(Intent.ACTION_USER_STARTED);
11867                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
11868                         | Intent.FLAG_RECEIVER_FOREGROUND);
11869                 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11870                 broadcastIntentLocked(null, null, intent,
11871                         null, null, 0, null, null, null, AppOpsManager.OP_NONE,
11872                         null, false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
11873                 intent = new Intent(Intent.ACTION_USER_STARTING);
11874                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11875                 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11876                 broadcastIntentLocked(null, null, intent,
11877                         null, new IIntentReceiver.Stub() {
11878                             @Override
11879                             public void performReceive(Intent intent, int resultCode, String data,
11880                                     Bundle extras, boolean ordered, boolean sticky, int sendingUser)
11881                                     throws RemoteException {
11882                             }
11883                         }, 0, null, null,
11884                         new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
11885                         null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
11886             } catch (Throwable t) {
11887                 Slog.wtf(TAG, "Failed sending first user broadcasts", t);
11888             } finally {
11889                 Binder.restoreCallingIdentity(ident);
11890             }
11891             mStackSupervisor.resumeTopActivitiesLocked();
11892             sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
11893         }
11894     }
11895
11896     private boolean makeAppCrashingLocked(ProcessRecord app,
11897             String shortMsg, String longMsg, String stackTrace) {
11898         app.crashing = true;
11899         app.crashingReport = generateProcessError(app,
11900                 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
11901         startAppProblemLocked(app);
11902         app.stopFreezingAllLocked();
11903         return handleAppCrashLocked(app, "force-crash" /*reason*/, shortMsg, longMsg, stackTrace);
11904     }
11905
11906     private void makeAppNotRespondingLocked(ProcessRecord app,
11907             String activity, String shortMsg, String longMsg) {
11908         app.notResponding = true;
11909         app.notRespondingReport = generateProcessError(app,
11910                 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
11911                 activity, shortMsg, longMsg, null);
11912         startAppProblemLocked(app);
11913         app.stopFreezingAllLocked();
11914     }
11915
11916     /**
11917      * Generate a process error record, suitable for attachment to a ProcessRecord.
11918      *
11919      * @param app The ProcessRecord in which the error occurred.
11920      * @param condition Crashing, Application Not Responding, etc.  Values are defined in
11921      *                      ActivityManager.AppErrorStateInfo
11922      * @param activity The activity associated with the crash, if known.
11923      * @param shortMsg Short message describing the crash.
11924      * @param longMsg Long message describing the crash.
11925      * @param stackTrace Full crash stack trace, may be null.
11926      *
11927      * @return Returns a fully-formed AppErrorStateInfo record.
11928      */
11929     private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
11930             int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
11931         ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
11932
11933         report.condition = condition;
11934         report.processName = app.processName;
11935         report.pid = app.pid;
11936         report.uid = app.info.uid;
11937         report.tag = activity;
11938         report.shortMsg = shortMsg;
11939         report.longMsg = longMsg;
11940         report.stackTrace = stackTrace;
11941
11942         return report;
11943     }
11944
11945     void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
11946         synchronized (this) {
11947             app.crashing = false;
11948             app.crashingReport = null;
11949             app.notResponding = false;
11950             app.notRespondingReport = null;
11951             if (app.anrDialog == fromDialog) {
11952                 app.anrDialog = null;
11953             }
11954             if (app.waitDialog == fromDialog) {
11955                 app.waitDialog = null;
11956             }
11957             if (app.pid > 0 && app.pid != MY_PID) {
11958                 handleAppCrashLocked(app, "user-terminated" /*reason*/,
11959                         null /*shortMsg*/, null /*longMsg*/, null /*stackTrace*/);
11960                 app.kill("user request after error", true);
11961             }
11962         }
11963     }
11964
11965     private boolean handleAppCrashLocked(ProcessRecord app, String reason,
11966             String shortMsg, String longMsg, String stackTrace) {
11967         long now = SystemClock.uptimeMillis();
11968
11969         Long crashTime;
11970         if (!app.isolated) {
11971             crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
11972         } else {
11973             crashTime = null;
11974         }
11975         if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
11976             // This process loses!
11977             Slog.w(TAG, "Process " + app.info.processName
11978                     + " has crashed too many times: killing!");
11979             EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
11980                     app.userId, app.info.processName, app.uid);
11981             mStackSupervisor.handleAppCrashLocked(app);
11982             if (!app.persistent) {
11983                 // We don't want to start this process again until the user
11984                 // explicitly does so...  but for persistent process, we really
11985                 // need to keep it running.  If a persistent process is actually
11986                 // repeatedly crashing, then badness for everyone.
11987                 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
11988                         app.info.processName);
11989                 if (!app.isolated) {
11990                     // XXX We don't have a way to mark isolated processes
11991                     // as bad, since they don't have a peristent identity.
11992                     mBadProcesses.put(app.info.processName, app.uid,
11993                             new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
11994                     mProcessCrashTimes.remove(app.info.processName, app.uid);
11995                 }
11996                 app.bad = true;
11997                 app.removed = true;
11998                 // Don't let services in this process be restarted and potentially
11999                 // annoy the user repeatedly.  Unless it is persistent, since those
12000                 // processes run critical code.
12001                 removeProcessLocked(app, false, false, "crash");
12002                 mStackSupervisor.resumeTopActivitiesLocked();
12003                 return false;
12004             }
12005             mStackSupervisor.resumeTopActivitiesLocked();
12006         } else {
12007             mStackSupervisor.finishTopRunningActivityLocked(app, reason);
12008         }
12009
12010         // Bump up the crash count of any services currently running in the proc.
12011         for (int i=app.services.size()-1; i>=0; i--) {
12012             // Any services running in the application need to be placed
12013             // back in the pending list.
12014             ServiceRecord sr = app.services.valueAt(i);
12015             sr.crashCount++;
12016         }
12017
12018         // If the crashing process is what we consider to be the "home process" and it has been
12019         // replaced by a third-party app, clear the package preferred activities from packages
12020         // with a home activity running in the process to prevent a repeatedly crashing app
12021         // from blocking the user to manually clear the list.
12022         final ArrayList<ActivityRecord> activities = app.activities;
12023         if (app == mHomeProcess && activities.size() > 0
12024                     && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
12025             for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
12026                 final ActivityRecord r = activities.get(activityNdx);
12027                 if (r.isHomeActivity()) {
12028                     Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
12029                     try {
12030                         ActivityThread.getPackageManager()
12031                                 .clearPackagePreferredActivities(r.packageName);
12032                     } catch (RemoteException c) {
12033                         // pm is in same process, this will never happen.
12034                     }
12035                 }
12036             }
12037         }
12038
12039         if (!app.isolated) {
12040             // XXX Can't keep track of crash times for isolated processes,
12041             // because they don't have a perisistent identity.
12042             mProcessCrashTimes.put(app.info.processName, app.uid, now);
12043         }
12044
12045         if (app.crashHandler != null) mHandler.post(app.crashHandler);
12046         return true;
12047     }
12048
12049     void startAppProblemLocked(ProcessRecord app) {
12050         // If this app is not running under the current user, then we
12051         // can't give it a report button because that would require
12052         // launching the report UI under a different user.
12053         app.errorReportReceiver = null;
12054
12055         for (int userId : mCurrentProfileIds) {
12056             if (app.userId == userId) {
12057                 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
12058                         mContext, app.info.packageName, app.info.flags);
12059             }
12060         }
12061         skipCurrentReceiverLocked(app);
12062     }
12063
12064     void skipCurrentReceiverLocked(ProcessRecord app) {
12065         for (BroadcastQueue queue : mBroadcastQueues) {
12066             queue.skipCurrentReceiverLocked(app);
12067         }
12068     }
12069
12070     /**
12071      * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
12072      * The application process will exit immediately after this call returns.
12073      * @param app object of the crashing app, null for the system server
12074      * @param crashInfo describing the exception
12075      */
12076     public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
12077         ProcessRecord r = findAppProcess(app, "Crash");
12078         final String processName = app == null ? "system_server"
12079                 : (r == null ? "unknown" : r.processName);
12080
12081         handleApplicationCrashInner("crash", r, processName, crashInfo);
12082     }
12083
12084     /* Native crash reporting uses this inner version because it needs to be somewhat
12085      * decoupled from the AM-managed cleanup lifecycle
12086      */
12087     void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
12088             ApplicationErrorReport.CrashInfo crashInfo) {
12089         EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
12090                 UserHandle.getUserId(Binder.getCallingUid()), processName,
12091                 r == null ? -1 : r.info.flags,
12092                 crashInfo.exceptionClassName,
12093                 crashInfo.exceptionMessage,
12094                 crashInfo.throwFileName,
12095                 crashInfo.throwLineNumber);
12096
12097         addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
12098
12099         crashApplication(r, crashInfo);
12100     }
12101
12102     public void handleApplicationStrictModeViolation(
12103             IBinder app,
12104             int violationMask,
12105             StrictMode.ViolationInfo info) {
12106         ProcessRecord r = findAppProcess(app, "StrictMode");
12107         if (r == null) {
12108             return;
12109         }
12110
12111         if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
12112             Integer stackFingerprint = info.hashCode();
12113             boolean logIt = true;
12114             synchronized (mAlreadyLoggedViolatedStacks) {
12115                 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
12116                     logIt = false;
12117                     // TODO: sub-sample into EventLog for these, with
12118                     // the info.durationMillis?  Then we'd get
12119                     // the relative pain numbers, without logging all
12120                     // the stack traces repeatedly.  We'd want to do
12121                     // likewise in the client code, which also does
12122                     // dup suppression, before the Binder call.
12123                 } else {
12124                     if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
12125                         mAlreadyLoggedViolatedStacks.clear();
12126                     }
12127                     mAlreadyLoggedViolatedStacks.add(stackFingerprint);
12128                 }
12129             }
12130             if (logIt) {
12131                 logStrictModeViolationToDropBox(r, info);
12132             }
12133         }
12134
12135         if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
12136             AppErrorResult result = new AppErrorResult();
12137             synchronized (this) {
12138                 final long origId = Binder.clearCallingIdentity();
12139
12140                 Message msg = Message.obtain();
12141                 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
12142                 HashMap<String, Object> data = new HashMap<String, Object>();
12143                 data.put("result", result);
12144                 data.put("app", r);
12145                 data.put("violationMask", violationMask);
12146                 data.put("info", info);
12147                 msg.obj = data;
12148                 mUiHandler.sendMessage(msg);
12149
12150                 Binder.restoreCallingIdentity(origId);
12151             }
12152             int res = result.get();
12153             Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
12154         }
12155     }
12156
12157     // Depending on the policy in effect, there could be a bunch of
12158     // these in quick succession so we try to batch these together to
12159     // minimize disk writes, number of dropbox entries, and maximize
12160     // compression, by having more fewer, larger records.
12161     private void logStrictModeViolationToDropBox(
12162             ProcessRecord process,
12163             StrictMode.ViolationInfo info) {
12164         if (info == null) {
12165             return;
12166         }
12167         final boolean isSystemApp = process == null ||
12168                 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
12169                                        ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
12170         final String processName = process == null ? "unknown" : process.processName;
12171         final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
12172         final DropBoxManager dbox = (DropBoxManager)
12173                 mContext.getSystemService(Context.DROPBOX_SERVICE);
12174
12175         // Exit early if the dropbox isn't configured to accept this report type.
12176         if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
12177
12178         boolean bufferWasEmpty;
12179         boolean needsFlush;
12180         final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
12181         synchronized (sb) {
12182             bufferWasEmpty = sb.length() == 0;
12183             appendDropBoxProcessHeaders(process, processName, sb);
12184             sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
12185             sb.append("System-App: ").append(isSystemApp).append("\n");
12186             sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
12187             if (info.violationNumThisLoop != 0) {
12188                 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
12189             }
12190             if (info.numAnimationsRunning != 0) {
12191                 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
12192             }
12193             if (info.broadcastIntentAction != null) {
12194                 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
12195             }
12196             if (info.durationMillis != -1) {
12197                 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
12198             }
12199             if (info.numInstances != -1) {
12200                 sb.append("Instance-Count: ").append(info.numInstances).append("\n");
12201             }
12202             if (info.tags != null) {
12203                 for (String tag : info.tags) {
12204                     sb.append("Span-Tag: ").append(tag).append("\n");
12205                 }
12206             }
12207             sb.append("\n");
12208             if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
12209                 sb.append(info.crashInfo.stackTrace);
12210                 sb.append("\n");
12211             }
12212             if (info.message != null) {
12213                 sb.append(info.message);
12214                 sb.append("\n");
12215             }
12216
12217             // Only buffer up to ~64k.  Various logging bits truncate
12218             // things at 128k.
12219             needsFlush = (sb.length() > 64 * 1024);
12220         }
12221
12222         // Flush immediately if the buffer's grown too large, or this
12223         // is a non-system app.  Non-system apps are isolated with a
12224         // different tag & policy and not batched.
12225         //
12226         // Batching is useful during internal testing with
12227         // StrictMode settings turned up high.  Without batching,
12228         // thousands of separate files could be created on boot.
12229         if (!isSystemApp || needsFlush) {
12230             new Thread("Error dump: " + dropboxTag) {
12231                 @Override
12232                 public void run() {
12233                     String report;
12234                     synchronized (sb) {
12235                         report = sb.toString();
12236                         sb.delete(0, sb.length());
12237                         sb.trimToSize();
12238                     }
12239                     if (report.length() != 0) {
12240                         dbox.addText(dropboxTag, report);
12241                     }
12242                 }
12243             }.start();
12244             return;
12245         }
12246
12247         // System app batching:
12248         if (!bufferWasEmpty) {
12249             // An existing dropbox-writing thread is outstanding, so
12250             // we don't need to start it up.  The existing thread will
12251             // catch the buffer appends we just did.
12252             return;
12253         }
12254
12255         // Worker thread to both batch writes and to avoid blocking the caller on I/O.
12256         // (After this point, we shouldn't access AMS internal data structures.)
12257         new Thread("Error dump: " + dropboxTag) {
12258             @Override
12259             public void run() {
12260                 // 5 second sleep to let stacks arrive and be batched together
12261                 try {
12262                     Thread.sleep(5000);  // 5 seconds
12263                 } catch (InterruptedException e) {}
12264
12265                 String errorReport;
12266                 synchronized (mStrictModeBuffer) {
12267                     errorReport = mStrictModeBuffer.toString();
12268                     if (errorReport.length() == 0) {
12269                         return;
12270                     }
12271                     mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
12272                     mStrictModeBuffer.trimToSize();
12273                 }
12274                 dbox.addText(dropboxTag, errorReport);
12275             }
12276         }.start();
12277     }
12278
12279     /**
12280      * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
12281      * @param app object of the crashing app, null for the system server
12282      * @param tag reported by the caller
12283      * @param system whether this wtf is coming from the system
12284      * @param crashInfo describing the context of the error
12285      * @return true if the process should exit immediately (WTF is fatal)
12286      */
12287     public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
12288             final ApplicationErrorReport.CrashInfo crashInfo) {
12289         final int callingUid = Binder.getCallingUid();
12290         final int callingPid = Binder.getCallingPid();
12291
12292         if (system) {
12293             // If this is coming from the system, we could very well have low-level
12294             // system locks held, so we want to do this all asynchronously.  And we
12295             // never want this to become fatal, so there is that too.
12296             mHandler.post(new Runnable() {
12297                 @Override public void run() {
12298                     handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
12299                 }
12300             });
12301             return false;
12302         }
12303
12304         final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
12305                 crashInfo);
12306
12307         if (r != null && r.pid != Process.myPid() &&
12308                 Settings.Global.getInt(mContext.getContentResolver(),
12309                         Settings.Global.WTF_IS_FATAL, 0) != 0) {
12310             crashApplication(r, crashInfo);
12311             return true;
12312         } else {
12313             return false;
12314         }
12315     }
12316
12317     ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
12318             final ApplicationErrorReport.CrashInfo crashInfo) {
12319         final ProcessRecord r = findAppProcess(app, "WTF");
12320         final String processName = app == null ? "system_server"
12321                 : (r == null ? "unknown" : r.processName);
12322
12323         EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
12324                 processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
12325
12326         addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
12327
12328         return r;
12329     }
12330
12331     /**
12332      * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
12333      * @return the corresponding {@link ProcessRecord} object, or null if none could be found
12334      */
12335     private ProcessRecord findAppProcess(IBinder app, String reason) {
12336         if (app == null) {
12337             return null;
12338         }
12339
12340         synchronized (this) {
12341             final int NP = mProcessNames.getMap().size();
12342             for (int ip=0; ip<NP; ip++) {
12343                 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
12344                 final int NA = apps.size();
12345                 for (int ia=0; ia<NA; ia++) {
12346                     ProcessRecord p = apps.valueAt(ia);
12347                     if (p.thread != null && p.thread.asBinder() == app) {
12348                         return p;
12349                     }
12350                 }
12351             }
12352
12353             Slog.w(TAG, "Can't find mystery application for " + reason
12354                     + " from pid=" + Binder.getCallingPid()
12355                     + " uid=" + Binder.getCallingUid() + ": " + app);
12356             return null;
12357         }
12358     }
12359
12360     /**
12361      * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
12362      * to append various headers to the dropbox log text.
12363      */
12364     private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
12365             StringBuilder sb) {
12366         // Watchdog thread ends up invoking this function (with
12367         // a null ProcessRecord) to add the stack file to dropbox.
12368         // Do not acquire a lock on this (am) in such cases, as it
12369         // could cause a potential deadlock, if and when watchdog
12370         // is invoked due to unavailability of lock on am and it
12371         // would prevent watchdog from killing system_server.
12372         if (process == null) {
12373             sb.append("Process: ").append(processName).append("\n");
12374             return;
12375         }
12376         // Note: ProcessRecord 'process' is guarded by the service
12377         // instance.  (notably process.pkgList, which could otherwise change
12378         // concurrently during execution of this method)
12379         synchronized (this) {
12380             sb.append("Process: ").append(processName).append("\n");
12381             int flags = process.info.flags;
12382             IPackageManager pm = AppGlobals.getPackageManager();
12383             sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
12384             for (int ip=0; ip<process.pkgList.size(); ip++) {
12385                 String pkg = process.pkgList.keyAt(ip);
12386                 sb.append("Package: ").append(pkg);
12387                 try {
12388                     PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
12389                     if (pi != null) {
12390                         sb.append(" v").append(pi.versionCode);
12391                         if (pi.versionName != null) {
12392                             sb.append(" (").append(pi.versionName).append(")");
12393                         }
12394                     }
12395                 } catch (RemoteException e) {
12396                     Slog.e(TAG, "Error getting package info: " + pkg, e);
12397                 }
12398                 sb.append("\n");
12399             }
12400         }
12401     }
12402
12403     private static String processClass(ProcessRecord process) {
12404         if (process == null || process.pid == MY_PID) {
12405             return "system_server";
12406         } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
12407             return "system_app";
12408         } else {
12409             return "data_app";
12410         }
12411     }
12412
12413     /**
12414      * Write a description of an error (crash, WTF, ANR) to the drop box.
12415      * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
12416      * @param process which caused the error, null means the system server
12417      * @param activity which triggered the error, null if unknown
12418      * @param parent activity related to the error, null if unknown
12419      * @param subject line related to the error, null if absent
12420      * @param report in long form describing the error, null if absent
12421      * @param logFile to include in the report, null if none
12422      * @param crashInfo giving an application stack trace, null if absent
12423      */
12424     public void addErrorToDropBox(String eventType,
12425             ProcessRecord process, String processName, ActivityRecord activity,
12426             ActivityRecord parent, String subject,
12427             final String report, final File logFile,
12428             final ApplicationErrorReport.CrashInfo crashInfo) {
12429         // NOTE -- this must never acquire the ActivityManagerService lock,
12430         // otherwise the watchdog may be prevented from resetting the system.
12431
12432         final String dropboxTag = processClass(process) + "_" + eventType;
12433         final DropBoxManager dbox = (DropBoxManager)
12434                 mContext.getSystemService(Context.DROPBOX_SERVICE);
12435
12436         // Exit early if the dropbox isn't configured to accept this report type.
12437         if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
12438
12439         final StringBuilder sb = new StringBuilder(1024);
12440         appendDropBoxProcessHeaders(process, processName, sb);
12441         if (activity != null) {
12442             sb.append("Activity: ").append(activity.shortComponentName).append("\n");
12443         }
12444         if (parent != null && parent.app != null && parent.app.pid != process.pid) {
12445             sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
12446         }
12447         if (parent != null && parent != activity) {
12448             sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
12449         }
12450         if (subject != null) {
12451             sb.append("Subject: ").append(subject).append("\n");
12452         }
12453         sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
12454         if (Debug.isDebuggerConnected()) {
12455             sb.append("Debugger: Connected\n");
12456         }
12457         sb.append("\n");
12458
12459         // Do the rest in a worker thread to avoid blocking the caller on I/O
12460         // (After this point, we shouldn't access AMS internal data structures.)
12461         Thread worker = new Thread("Error dump: " + dropboxTag) {
12462             @Override
12463             public void run() {
12464                 if (report != null) {
12465                     sb.append(report);
12466                 }
12467                 if (logFile != null) {
12468                     try {
12469                         sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
12470                                     "\n\n[[TRUNCATED]]"));
12471                     } catch (IOException e) {
12472                         Slog.e(TAG, "Error reading " + logFile, e);
12473                     }
12474                 }
12475                 if (crashInfo != null && crashInfo.stackTrace != null) {
12476                     sb.append(crashInfo.stackTrace);
12477                 }
12478
12479                 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
12480                 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
12481                 if (lines > 0) {
12482                     sb.append("\n");
12483
12484                     // Merge several logcat streams, and take the last N lines
12485                     InputStreamReader input = null;
12486                     try {
12487                         java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
12488                                 "-v", "time", "-b", "events", "-b", "system", "-b", "main",
12489                                 "-b", "crash",
12490                                 "-t", String.valueOf(lines)).redirectErrorStream(true).start();
12491
12492                         try { logcat.getOutputStream().close(); } catch (IOException e) {}
12493                         try { logcat.getErrorStream().close(); } catch (IOException e) {}
12494                         input = new InputStreamReader(logcat.getInputStream());
12495
12496                         int num;
12497                         char[] buf = new char[8192];
12498                         while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
12499                     } catch (IOException e) {
12500                         Slog.e(TAG, "Error running logcat", e);
12501                     } finally {
12502                         if (input != null) try { input.close(); } catch (IOException e) {}
12503                     }
12504                 }
12505
12506                 dbox.addText(dropboxTag, sb.toString());
12507             }
12508         };
12509
12510         if (process == null) {
12511             // If process is null, we are being called from some internal code
12512             // and may be about to die -- run this synchronously.
12513             worker.run();
12514         } else {
12515             worker.start();
12516         }
12517     }
12518
12519     /**
12520      * Bring up the "unexpected error" dialog box for a crashing app.
12521      * Deal with edge cases (intercepts from instrumented applications,
12522      * ActivityController, error intent receivers, that sort of thing).
12523      * @param r the application crashing
12524      * @param crashInfo describing the failure
12525      */
12526     private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
12527         long timeMillis = System.currentTimeMillis();
12528         String shortMsg = crashInfo.exceptionClassName;
12529         String longMsg = crashInfo.exceptionMessage;
12530         String stackTrace = crashInfo.stackTrace;
12531         if (shortMsg != null && longMsg != null) {
12532             longMsg = shortMsg + ": " + longMsg;
12533         } else if (shortMsg != null) {
12534             longMsg = shortMsg;
12535         }
12536
12537         AppErrorResult result = new AppErrorResult();
12538         synchronized (this) {
12539             if (mController != null) {
12540                 try {
12541                     String name = r != null ? r.processName : null;
12542                     int pid = r != null ? r.pid : Binder.getCallingPid();
12543                     int uid = r != null ? r.info.uid : Binder.getCallingUid();
12544                     if (!mController.appCrashed(name, pid,
12545                             shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
12546                         if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
12547                                 && "Native crash".equals(crashInfo.exceptionClassName)) {
12548                             Slog.w(TAG, "Skip killing native crashed app " + name
12549                                     + "(" + pid + ") during testing");
12550                         } else {
12551                             Slog.w(TAG, "Force-killing crashed app " + name
12552                                     + " at watcher's request");
12553                             if (r != null) {
12554                                 r.kill("crash", true);
12555                             } else {
12556                                 // Huh.
12557                                 Process.killProcess(pid);
12558                                 killProcessGroup(uid, pid);
12559                             }
12560                         }
12561                         return;
12562                     }
12563                 } catch (RemoteException e) {
12564                     mController = null;
12565                     Watchdog.getInstance().setActivityController(null);
12566                 }
12567             }
12568
12569             final long origId = Binder.clearCallingIdentity();
12570
12571             // If this process is running instrumentation, finish it.
12572             if (r != null && r.instrumentationClass != null) {
12573                 Slog.w(TAG, "Error in app " + r.processName
12574                       + " running instrumentation " + r.instrumentationClass + ":");
12575                 if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
12576                 if (longMsg != null) Slog.w(TAG, "  " + longMsg);
12577                 Bundle info = new Bundle();
12578                 info.putString("shortMsg", shortMsg);
12579                 info.putString("longMsg", longMsg);
12580                 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
12581                 Binder.restoreCallingIdentity(origId);
12582                 return;
12583             }
12584
12585             // Log crash in battery stats.
12586             if (r != null) {
12587                 mBatteryStatsService.noteProcessCrash(r.processName, r.uid);
12588             }
12589
12590             // If we can't identify the process or it's already exceeded its crash quota,
12591             // quit right away without showing a crash dialog.
12592             if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
12593                 Binder.restoreCallingIdentity(origId);
12594                 return;
12595             }
12596
12597             Message msg = Message.obtain();
12598             msg.what = SHOW_ERROR_MSG;
12599             HashMap data = new HashMap();
12600             data.put("result", result);
12601             data.put("app", r);
12602             msg.obj = data;
12603             mUiHandler.sendMessage(msg);
12604
12605             Binder.restoreCallingIdentity(origId);
12606         }
12607
12608         int res = result.get();
12609
12610         Intent appErrorIntent = null;
12611         synchronized (this) {
12612             if (r != null && !r.isolated) {
12613                 // XXX Can't keep track of crash time for isolated processes,
12614                 // since they don't have a persistent identity.
12615                 mProcessCrashTimes.put(r.info.processName, r.uid,
12616                         SystemClock.uptimeMillis());
12617             }
12618             if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
12619                 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
12620             }
12621         }
12622
12623         if (appErrorIntent != null) {
12624             try {
12625                 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
12626             } catch (ActivityNotFoundException e) {
12627                 Slog.w(TAG, "bug report receiver dissappeared", e);
12628             }
12629         }
12630     }
12631
12632     Intent createAppErrorIntentLocked(ProcessRecord r,
12633             long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12634         ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
12635         if (report == null) {
12636             return null;
12637         }
12638         Intent result = new Intent(Intent.ACTION_APP_ERROR);
12639         result.setComponent(r.errorReportReceiver);
12640         result.putExtra(Intent.EXTRA_BUG_REPORT, report);
12641         result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
12642         return result;
12643     }
12644
12645     private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
12646             long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12647         if (r.errorReportReceiver == null) {
12648             return null;
12649         }
12650
12651         if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
12652             return null;
12653         }
12654
12655         ApplicationErrorReport report = new ApplicationErrorReport();
12656         report.packageName = r.info.packageName;
12657         report.installerPackageName = r.errorReportReceiver.getPackageName();
12658         report.processName = r.processName;
12659         report.time = timeMillis;
12660         report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
12661
12662         if (r.crashing || r.forceCrashReport) {
12663             report.type = ApplicationErrorReport.TYPE_CRASH;
12664             report.crashInfo = crashInfo;
12665         } else if (r.notResponding) {
12666             report.type = ApplicationErrorReport.TYPE_ANR;
12667             report.anrInfo = new ApplicationErrorReport.AnrInfo();
12668
12669             report.anrInfo.activity = r.notRespondingReport.tag;
12670             report.anrInfo.cause = r.notRespondingReport.shortMsg;
12671             report.anrInfo.info = r.notRespondingReport.longMsg;
12672         }
12673
12674         return report;
12675     }
12676
12677     public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
12678         enforceNotIsolatedCaller("getProcessesInErrorState");
12679         // assume our apps are happy - lazy create the list
12680         List<ActivityManager.ProcessErrorStateInfo> errList = null;
12681
12682         final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12683                 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12684         int userId = UserHandle.getUserId(Binder.getCallingUid());
12685
12686         synchronized (this) {
12687
12688             // iterate across all processes
12689             for (int i=mLruProcesses.size()-1; i>=0; i--) {
12690                 ProcessRecord app = mLruProcesses.get(i);
12691                 if (!allUsers && app.userId != userId) {
12692                     continue;
12693                 }
12694                 if ((app.thread != null) && (app.crashing || app.notResponding)) {
12695                     // This one's in trouble, so we'll generate a report for it
12696                     // crashes are higher priority (in case there's a crash *and* an anr)
12697                     ActivityManager.ProcessErrorStateInfo report = null;
12698                     if (app.crashing) {
12699                         report = app.crashingReport;
12700                     } else if (app.notResponding) {
12701                         report = app.notRespondingReport;
12702                     }
12703
12704                     if (report != null) {
12705                         if (errList == null) {
12706                             errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
12707                         }
12708                         errList.add(report);
12709                     } else {
12710                         Slog.w(TAG, "Missing app error report, app = " + app.processName +
12711                                 " crashing = " + app.crashing +
12712                                 " notResponding = " + app.notResponding);
12713                     }
12714                 }
12715             }
12716         }
12717
12718         return errList;
12719     }
12720
12721     static int procStateToImportance(int procState, int memAdj,
12722             ActivityManager.RunningAppProcessInfo currApp) {
12723         int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
12724         if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
12725             currApp.lru = memAdj;
12726         } else {
12727             currApp.lru = 0;
12728         }
12729         return imp;
12730     }
12731
12732     private void fillInProcMemInfo(ProcessRecord app,
12733             ActivityManager.RunningAppProcessInfo outInfo) {
12734         outInfo.pid = app.pid;
12735         outInfo.uid = app.info.uid;
12736         if (mHeavyWeightProcess == app) {
12737             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
12738         }
12739         if (app.persistent) {
12740             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
12741         }
12742         if (app.activities.size() > 0) {
12743             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
12744         }
12745         outInfo.lastTrimLevel = app.trimMemoryLevel;
12746         int adj = app.curAdj;
12747         int procState = app.curProcState;
12748         outInfo.importance = procStateToImportance(procState, adj, outInfo);
12749         outInfo.importanceReasonCode = app.adjTypeCode;
12750         outInfo.processState = app.curProcState;
12751     }
12752
12753     public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
12754         enforceNotIsolatedCaller("getRunningAppProcesses");
12755
12756         final int callingUid = Binder.getCallingUid();
12757
12758         // Lazy instantiation of list
12759         List<ActivityManager.RunningAppProcessInfo> runList = null;
12760         final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12761                 callingUid) == PackageManager.PERMISSION_GRANTED;
12762         final int userId = UserHandle.getUserId(callingUid);
12763         final boolean allUids = isGetTasksAllowed(
12764                 "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
12765
12766         synchronized (this) {
12767             // Iterate across all processes
12768             for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
12769                 ProcessRecord app = mLruProcesses.get(i);
12770                 if ((!allUsers && app.userId != userId)
12771                         || (!allUids && app.uid != callingUid)) {
12772                     continue;
12773                 }
12774                 if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
12775                     // Generate process state info for running application
12776                     ActivityManager.RunningAppProcessInfo currApp =
12777                         new ActivityManager.RunningAppProcessInfo(app.processName,
12778                                 app.pid, app.getPackageList());
12779                     fillInProcMemInfo(app, currApp);
12780                     if (app.adjSource instanceof ProcessRecord) {
12781                         currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
12782                         currApp.importanceReasonImportance =
12783                                 ActivityManager.RunningAppProcessInfo.procStateToImportance(
12784                                         app.adjSourceProcState);
12785                     } else if (app.adjSource instanceof ActivityRecord) {
12786                         ActivityRecord r = (ActivityRecord)app.adjSource;
12787                         if (r.app != null) currApp.importanceReasonPid = r.app.pid;
12788                     }
12789                     if (app.adjTarget instanceof ComponentName) {
12790                         currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
12791                     }
12792                     //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
12793                     //        + " lru=" + currApp.lru);
12794                     if (runList == null) {
12795                         runList = new ArrayList<>();
12796                     }
12797                     runList.add(currApp);
12798                 }
12799             }
12800         }
12801         return runList;
12802     }
12803
12804     public List<ApplicationInfo> getRunningExternalApplications() {
12805         enforceNotIsolatedCaller("getRunningExternalApplications");
12806         List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
12807         List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
12808         if (runningApps != null && runningApps.size() > 0) {
12809             Set<String> extList = new HashSet<String>();
12810             for (ActivityManager.RunningAppProcessInfo app : runningApps) {
12811                 if (app.pkgList != null) {
12812                     for (String pkg : app.pkgList) {
12813                         extList.add(pkg);
12814                     }
12815                 }
12816             }
12817             IPackageManager pm = AppGlobals.getPackageManager();
12818             for (String pkg : extList) {
12819                 try {
12820                     ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
12821                     if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
12822                         retList.add(info);
12823                     }
12824                 } catch (RemoteException e) {
12825                 }
12826             }
12827         }
12828         return retList;
12829     }
12830
12831     @Override
12832     public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
12833         enforceNotIsolatedCaller("getMyMemoryState");
12834         synchronized (this) {
12835             ProcessRecord proc;
12836             synchronized (mPidsSelfLocked) {
12837                 proc = mPidsSelfLocked.get(Binder.getCallingPid());
12838             }
12839             fillInProcMemInfo(proc, outInfo);
12840         }
12841     }
12842
12843     @Override
12844     protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
12845         if (checkCallingPermission(android.Manifest.permission.DUMP)
12846                 != PackageManager.PERMISSION_GRANTED) {
12847             pw.println("Permission Denial: can't dump ActivityManager from from pid="
12848                     + Binder.getCallingPid()
12849                     + ", uid=" + Binder.getCallingUid()
12850                     + " without permission "
12851                     + android.Manifest.permission.DUMP);
12852             return;
12853         }
12854
12855         boolean dumpAll = false;
12856         boolean dumpClient = false;
12857         String dumpPackage = null;
12858
12859         int opti = 0;
12860         while (opti < args.length) {
12861             String opt = args[opti];
12862             if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12863                 break;
12864             }
12865             opti++;
12866             if ("-a".equals(opt)) {
12867                 dumpAll = true;
12868             } else if ("-c".equals(opt)) {
12869                 dumpClient = true;
12870             } else if ("-p".equals(opt)) {
12871                 if (opti < args.length) {
12872                     dumpPackage = args[opti];
12873                     opti++;
12874                 } else {
12875                     pw.println("Error: -p option requires package argument");
12876                     return;
12877                 }
12878                 dumpClient = true;
12879             } else if ("-h".equals(opt)) {
12880                 pw.println("Activity manager dump options:");
12881                 pw.println("  [-a] [-c] [-p package] [-h] [cmd] ...");
12882                 pw.println("  cmd may be one of:");
12883                 pw.println("    a[ctivities]: activity stack state");
12884                 pw.println("    r[recents]: recent activities state");
12885                 pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
12886                 pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
12887                 pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
12888                 pw.println("    o[om]: out of memory management");
12889                 pw.println("    perm[issions]: URI permission grant state");
12890                 pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
12891                 pw.println("    provider [COMP_SPEC]: provider client-side state");
12892                 pw.println("    s[ervices] [COMP_SPEC ...]: service state");
12893                 pw.println("    as[sociations]: tracked app associations");
12894                 pw.println("    service [COMP_SPEC]: service client-side state");
12895                 pw.println("    package [PACKAGE_NAME]: all state related to given package");
12896                 pw.println("    all: dump all activities");
12897                 pw.println("    top: dump the top activity");
12898                 pw.println("    write: write all pending state to storage");
12899                 pw.println("    track-associations: enable association tracking");
12900                 pw.println("    untrack-associations: disable and clear association tracking");
12901                 pw.println("  cmd may also be a COMP_SPEC to dump activities.");
12902                 pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
12903                 pw.println("    a partial substring in a component name, a");
12904                 pw.println("    hex object identifier.");
12905                 pw.println("  -a: include all available server state.");
12906                 pw.println("  -c: include client state.");
12907                 pw.println("  -p: limit output to given package.");
12908                 return;
12909             } else {
12910                 pw.println("Unknown argument: " + opt + "; use -h for help");
12911             }
12912         }
12913
12914         long origId = Binder.clearCallingIdentity();
12915         boolean more = false;
12916         // Is the caller requesting to dump a particular piece of data?
12917         if (opti < args.length) {
12918             String cmd = args[opti];
12919             opti++;
12920             if ("activities".equals(cmd) || "a".equals(cmd)) {
12921                 synchronized (this) {
12922                     dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
12923                 }
12924             } else if ("recents".equals(cmd) || "r".equals(cmd)) {
12925                 synchronized (this) {
12926                     dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
12927                 }
12928             } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
12929                 String[] newArgs;
12930                 String name;
12931                 if (opti >= args.length) {
12932                     name = null;
12933                     newArgs = EMPTY_STRING_ARRAY;
12934                 } else {
12935                     dumpPackage = args[opti];
12936                     opti++;
12937                     newArgs = new String[args.length - opti];
12938                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12939                             args.length - opti);
12940                 }
12941                 synchronized (this) {
12942                     dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
12943                 }
12944             } else if ("intents".equals(cmd) || "i".equals(cmd)) {
12945                 String[] newArgs;
12946                 String name;
12947                 if (opti >= args.length) {
12948                     name = null;
12949                     newArgs = EMPTY_STRING_ARRAY;
12950                 } else {
12951                     dumpPackage = args[opti];
12952                     opti++;
12953                     newArgs = new String[args.length - opti];
12954                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12955                             args.length - opti);
12956                 }
12957                 synchronized (this) {
12958                     dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
12959                 }
12960             } else if ("processes".equals(cmd) || "p".equals(cmd)) {
12961                 String[] newArgs;
12962                 String name;
12963                 if (opti >= args.length) {
12964                     name = null;
12965                     newArgs = EMPTY_STRING_ARRAY;
12966                 } else {
12967                     dumpPackage = args[opti];
12968                     opti++;
12969                     newArgs = new String[args.length - opti];
12970                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12971                             args.length - opti);
12972                 }
12973                 synchronized (this) {
12974                     dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
12975                 }
12976             } else if ("oom".equals(cmd) || "o".equals(cmd)) {
12977                 synchronized (this) {
12978                     dumpOomLocked(fd, pw, args, opti, true);
12979                 }
12980             } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
12981                 synchronized (this) {
12982                     dumpPermissionsLocked(fd, pw, args, opti, true, null);
12983                 }
12984             } else if ("provider".equals(cmd)) {
12985                 String[] newArgs;
12986                 String name;
12987                 if (opti >= args.length) {
12988                     name = null;
12989                     newArgs = EMPTY_STRING_ARRAY;
12990                 } else {
12991                     name = args[opti];
12992                     opti++;
12993                     newArgs = new String[args.length - opti];
12994                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12995                 }
12996                 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
12997                     pw.println("No providers match: " + name);
12998                     pw.println("Use -h for help.");
12999                 }
13000             } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
13001                 synchronized (this) {
13002                     dumpProvidersLocked(fd, pw, args, opti, true, null);
13003                 }
13004             } else if ("service".equals(cmd)) {
13005                 String[] newArgs;
13006                 String name;
13007                 if (opti >= args.length) {
13008                     name = null;
13009                     newArgs = EMPTY_STRING_ARRAY;
13010                 } else {
13011                     name = args[opti];
13012                     opti++;
13013                     newArgs = new String[args.length - opti];
13014                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13015                             args.length - opti);
13016                 }
13017                 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
13018                     pw.println("No services match: " + name);
13019                     pw.println("Use -h for help.");
13020                 }
13021             } else if ("package".equals(cmd)) {
13022                 String[] newArgs;
13023                 if (opti >= args.length) {
13024                     pw.println("package: no package name specified");
13025                     pw.println("Use -h for help.");
13026                 } else {
13027                     dumpPackage = args[opti];
13028                     opti++;
13029                     newArgs = new String[args.length - opti];
13030                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13031                             args.length - opti);
13032                     args = newArgs;
13033                     opti = 0;
13034                     more = true;
13035                 }
13036             } else if ("associations".equals(cmd) || "as".equals(cmd)) {
13037                 synchronized (this) {
13038                     dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13039                 }
13040             } else if ("services".equals(cmd) || "s".equals(cmd)) {
13041                 synchronized (this) {
13042                     mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13043                 }
13044             } else if ("write".equals(cmd)) {
13045                 mTaskPersister.flush();
13046                 pw.println("All tasks persisted.");
13047                 return;
13048             } else if ("track-associations".equals(cmd)) {
13049                 synchronized (this) {
13050                     if (!mTrackingAssociations) {
13051                         mTrackingAssociations = true;
13052                         pw.println("Association tracking started.");
13053                     } else {
13054                         pw.println("Association tracking already enabled.");
13055                     }
13056                 }
13057                 return;
13058             } else if ("untrack-associations".equals(cmd)) {
13059                 synchronized (this) {
13060                     if (mTrackingAssociations) {
13061                         mTrackingAssociations = false;
13062                         mAssociations.clear();
13063                         pw.println("Association tracking stopped.");
13064                     } else {
13065                         pw.println("Association tracking not running.");
13066                     }
13067                 }
13068                 return;
13069             } else {
13070                 // Dumping a single activity?
13071                 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
13072                     pw.println("Bad activity command, or no activities match: " + cmd);
13073                     pw.println("Use -h for help.");
13074                 }
13075             }
13076             if (!more) {
13077                 Binder.restoreCallingIdentity(origId);
13078                 return;
13079             }
13080         }
13081
13082         // No piece of data specified, dump everything.
13083         synchronized (this) {
13084             dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13085             pw.println();
13086             if (dumpAll) {
13087                 pw.println("-------------------------------------------------------------------------------");
13088             }
13089             dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13090             pw.println();
13091             if (dumpAll) {
13092                 pw.println("-------------------------------------------------------------------------------");
13093             }
13094             dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13095             pw.println();
13096             if (dumpAll) {
13097                 pw.println("-------------------------------------------------------------------------------");
13098             }
13099             dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13100             pw.println();
13101             if (dumpAll) {
13102                 pw.println("-------------------------------------------------------------------------------");
13103             }
13104             mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13105             pw.println();
13106             if (dumpAll) {
13107                 pw.println("-------------------------------------------------------------------------------");
13108             }
13109             dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13110             pw.println();
13111             if (dumpAll) {
13112                 pw.println("-------------------------------------------------------------------------------");
13113             }
13114             dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13115             if (mAssociations.size() > 0) {
13116                 pw.println();
13117                 if (dumpAll) {
13118                     pw.println("-------------------------------------------------------------------------------");
13119                 }
13120                 dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13121             }
13122             pw.println();
13123             if (dumpAll) {
13124                 pw.println("-------------------------------------------------------------------------------");
13125             }
13126             dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13127         }
13128         Binder.restoreCallingIdentity(origId);
13129     }
13130
13131     void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13132             int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
13133         pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
13134
13135         boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
13136                 dumpPackage);
13137         boolean needSep = printedAnything;
13138
13139         boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
13140                 dumpPackage, needSep, "  mFocusedActivity: ");
13141         if (printed) {
13142             printedAnything = true;
13143             needSep = false;
13144         }
13145
13146         if (dumpPackage == null) {
13147             if (needSep) {
13148                 pw.println();
13149             }
13150             needSep = true;
13151             printedAnything = true;
13152             mStackSupervisor.dump(pw, "  ");
13153         }
13154
13155         if (!printedAnything) {
13156             pw.println("  (nothing)");
13157         }
13158     }
13159
13160     void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13161             int opti, boolean dumpAll, String dumpPackage) {
13162         pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
13163
13164         boolean printedAnything = false;
13165
13166         if (mRecentTasks != null && mRecentTasks.size() > 0) {
13167             boolean printedHeader = false;
13168
13169             final int N = mRecentTasks.size();
13170             for (int i=0; i<N; i++) {
13171                 TaskRecord tr = mRecentTasks.get(i);
13172                 if (dumpPackage != null) {
13173                     if (tr.realActivity == null ||
13174                             !dumpPackage.equals(tr.realActivity)) {
13175                         continue;
13176                     }
13177                 }
13178                 if (!printedHeader) {
13179                     pw.println("  Recent tasks:");
13180                     printedHeader = true;
13181                     printedAnything = true;
13182                 }
13183                 pw.print("  * Recent #"); pw.print(i); pw.print(": ");
13184                         pw.println(tr);
13185                 if (dumpAll) {
13186                     mRecentTasks.get(i).dump(pw, "    ");
13187                 }
13188             }
13189         }
13190
13191         if (!printedAnything) {
13192             pw.println("  (nothing)");
13193         }
13194     }
13195
13196     void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13197             int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
13198         pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
13199
13200         int dumpUid = 0;
13201         if (dumpPackage != null) {
13202             IPackageManager pm = AppGlobals.getPackageManager();
13203             try {
13204                 dumpUid = pm.getPackageUid(dumpPackage, 0);
13205             } catch (RemoteException e) {
13206             }
13207         }
13208
13209         boolean printedAnything = false;
13210
13211         final long now = SystemClock.uptimeMillis();
13212
13213         for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
13214             ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
13215                     = mAssociations.valueAt(i1);
13216             for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
13217                 SparseArray<ArrayMap<String, Association>> sourceUids
13218                         = targetComponents.valueAt(i2);
13219                 for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
13220                     ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
13221                     for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
13222                         Association ass = sourceProcesses.valueAt(i4);
13223                         if (dumpPackage != null) {
13224                             if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
13225                                     && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
13226                                 continue;
13227                             }
13228                         }
13229                         printedAnything = true;
13230                         pw.print("  ");
13231                         pw.print(ass.mTargetProcess);
13232                         pw.print("/");
13233                         UserHandle.formatUid(pw, ass.mTargetUid);
13234                         pw.print(" <- ");
13235                         pw.print(ass.mSourceProcess);
13236                         pw.print("/");
13237                         UserHandle.formatUid(pw, ass.mSourceUid);
13238                         pw.println();
13239                         pw.print("    via ");
13240                         pw.print(ass.mTargetComponent.flattenToShortString());
13241                         pw.println();
13242                         pw.print("    ");
13243                         long dur = ass.mTime;
13244                         if (ass.mNesting > 0) {
13245                             dur += now - ass.mStartTime;
13246                         }
13247                         TimeUtils.formatDuration(dur, pw);
13248                         pw.print(" (");
13249                         pw.print(ass.mCount);
13250                         pw.println(" times)");
13251                         if (ass.mNesting > 0) {
13252                             pw.print("    ");
13253                             pw.print(" Currently active: ");
13254                             TimeUtils.formatDuration(now - ass.mStartTime, pw);
13255                             pw.println();
13256                         }
13257                     }
13258                 }
13259             }
13260
13261         }
13262
13263         if (!printedAnything) {
13264             pw.println("  (nothing)");
13265         }
13266     }
13267
13268     void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13269             int opti, boolean dumpAll, String dumpPackage) {
13270         boolean needSep = false;
13271         boolean printedAnything = false;
13272         int numPers = 0;
13273
13274         pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
13275
13276         if (dumpAll) {
13277             final int NP = mProcessNames.getMap().size();
13278             for (int ip=0; ip<NP; ip++) {
13279                 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
13280                 final int NA = procs.size();
13281                 for (int ia=0; ia<NA; ia++) {
13282                     ProcessRecord r = procs.valueAt(ia);
13283                     if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13284                         continue;
13285                     }
13286                     if (!needSep) {
13287                         pw.println("  All known processes:");
13288                         needSep = true;
13289                         printedAnything = true;
13290                     }
13291                     pw.print(r.persistent ? "  *PERS*" : "  *APP*");
13292                         pw.print(" UID "); pw.print(procs.keyAt(ia));
13293                         pw.print(" "); pw.println(r);
13294                     r.dump(pw, "    ");
13295                     if (r.persistent) {
13296                         numPers++;
13297                     }
13298                 }
13299             }
13300         }
13301
13302         if (mIsolatedProcesses.size() > 0) {
13303             boolean printed = false;
13304             for (int i=0; i<mIsolatedProcesses.size(); i++) {
13305                 ProcessRecord r = mIsolatedProcesses.valueAt(i);
13306                 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13307                     continue;
13308                 }
13309                 if (!printed) {
13310                     if (needSep) {
13311                         pw.println();
13312                     }
13313                     pw.println("  Isolated process list (sorted by uid):");
13314                     printedAnything = true;
13315                     printed = true;
13316                     needSep = true;
13317                 }
13318                 pw.println(String.format("%sIsolated #%2d: %s",
13319                         "    ", i, r.toString()));
13320             }
13321         }
13322
13323         if (mActiveUids.size() > 0) {
13324             if (needSep) {
13325                 pw.println();
13326             }
13327             pw.println("  UID states:");
13328             for (int i=0; i<mActiveUids.size(); i++) {
13329                 UidRecord uidRec = mActiveUids.valueAt(i);
13330                 pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
13331                 pw.print(": "); pw.println(uidRec);
13332             }
13333             needSep = true;
13334             printedAnything = true;
13335         }
13336
13337         if (mLruProcesses.size() > 0) {
13338             if (needSep) {
13339                 pw.println();
13340             }
13341             pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
13342                     pw.print(" total, non-act at ");
13343                     pw.print(mLruProcesses.size()-mLruProcessActivityStart);
13344                     pw.print(", non-svc at ");
13345                     pw.print(mLruProcesses.size()-mLruProcessServiceStart);
13346                     pw.println("):");
13347             dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
13348             needSep = true;
13349             printedAnything = true;
13350         }
13351
13352         if (dumpAll || dumpPackage != null) {
13353             synchronized (mPidsSelfLocked) {
13354                 boolean printed = false;
13355                 for (int i=0; i<mPidsSelfLocked.size(); i++) {
13356                     ProcessRecord r = mPidsSelfLocked.valueAt(i);
13357                     if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13358                         continue;
13359                     }
13360                     if (!printed) {
13361                         if (needSep) pw.println();
13362                         needSep = true;
13363                         pw.println("  PID mappings:");
13364                         printed = true;
13365                         printedAnything = true;
13366                     }
13367                     pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
13368                         pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
13369                 }
13370             }
13371         }
13372
13373         if (mForegroundProcesses.size() > 0) {
13374             synchronized (mPidsSelfLocked) {
13375                 boolean printed = false;
13376                 for (int i=0; i<mForegroundProcesses.size(); i++) {
13377                     ProcessRecord r = mPidsSelfLocked.get(
13378                             mForegroundProcesses.valueAt(i).pid);
13379                     if (dumpPackage != null && (r == null
13380                             || !r.pkgList.containsKey(dumpPackage))) {
13381                         continue;
13382                     }
13383                     if (!printed) {
13384                         if (needSep) pw.println();
13385                         needSep = true;
13386                         pw.println("  Foreground Processes:");
13387                         printed = true;
13388                         printedAnything = true;
13389                     }
13390                     pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
13391                             pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
13392                 }
13393             }
13394         }
13395
13396         if (mPersistentStartingProcesses.size() > 0) {
13397             if (needSep) pw.println();
13398             needSep = true;
13399             printedAnything = true;
13400             pw.println("  Persisent processes that are starting:");
13401             dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
13402                     "Starting Norm", "Restarting PERS", dumpPackage);
13403         }
13404
13405         if (mRemovedProcesses.size() > 0) {
13406             if (needSep) pw.println();
13407             needSep = true;
13408             printedAnything = true;
13409             pw.println("  Processes that are being removed:");
13410             dumpProcessList(pw, this, mRemovedProcesses, "    ",
13411                     "Removed Norm", "Removed PERS", dumpPackage);
13412         }
13413
13414         if (mProcessesOnHold.size() > 0) {
13415             if (needSep) pw.println();
13416             needSep = true;
13417             printedAnything = true;
13418             pw.println("  Processes that are on old until the system is ready:");
13419             dumpProcessList(pw, this, mProcessesOnHold, "    ",
13420                     "OnHold Norm", "OnHold PERS", dumpPackage);
13421         }
13422
13423         needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
13424
13425         if (mProcessCrashTimes.getMap().size() > 0) {
13426             boolean printed = false;
13427             long now = SystemClock.uptimeMillis();
13428             final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
13429             final int NP = pmap.size();
13430             for (int ip=0; ip<NP; ip++) {
13431                 String pname = pmap.keyAt(ip);
13432                 SparseArray<Long> uids = pmap.valueAt(ip);
13433                 final int N = uids.size();
13434                 for (int i=0; i<N; i++) {
13435                     int puid = uids.keyAt(i);
13436                     ProcessRecord r = mProcessNames.get(pname, puid);
13437                     if (dumpPackage != null && (r == null
13438                             || !r.pkgList.containsKey(dumpPackage))) {
13439                         continue;
13440                     }
13441                     if (!printed) {
13442                         if (needSep) pw.println();
13443                         needSep = true;
13444                         pw.println("  Time since processes crashed:");
13445                         printed = true;
13446                         printedAnything = true;
13447                     }
13448                     pw.print("    Process "); pw.print(pname);
13449                             pw.print(" uid "); pw.print(puid);
13450                             pw.print(": last crashed ");
13451                             TimeUtils.formatDuration(now-uids.valueAt(i), pw);
13452                             pw.println(" ago");
13453                 }
13454             }
13455         }
13456
13457         if (mBadProcesses.getMap().size() > 0) {
13458             boolean printed = false;
13459             final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
13460             final int NP = pmap.size();
13461             for (int ip=0; ip<NP; ip++) {
13462                 String pname = pmap.keyAt(ip);
13463                 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
13464                 final int N = uids.size();
13465                 for (int i=0; i<N; i++) {
13466                     int puid = uids.keyAt(i);
13467                     ProcessRecord r = mProcessNames.get(pname, puid);
13468                     if (dumpPackage != null && (r == null
13469                             || !r.pkgList.containsKey(dumpPackage))) {
13470                         continue;
13471                     }
13472                     if (!printed) {
13473                         if (needSep) pw.println();
13474                         needSep = true;
13475                         pw.println("  Bad processes:");
13476                         printedAnything = true;
13477                     }
13478                     BadProcessInfo info = uids.valueAt(i);
13479                     pw.print("    Bad process "); pw.print(pname);
13480                             pw.print(" uid "); pw.print(puid);
13481                             pw.print(": crashed at time "); pw.println(info.time);
13482                     if (info.shortMsg != null) {
13483                         pw.print("      Short msg: "); pw.println(info.shortMsg);
13484                     }
13485                     if (info.longMsg != null) {
13486                         pw.print("      Long msg: "); pw.println(info.longMsg);
13487                     }
13488                     if (info.stack != null) {
13489                         pw.println("      Stack:");
13490                         int lastPos = 0;
13491                         for (int pos=0; pos<info.stack.length(); pos++) {
13492                             if (info.stack.charAt(pos) == '\n') {
13493                                 pw.print("        ");
13494                                 pw.write(info.stack, lastPos, pos-lastPos);
13495                                 pw.println();
13496                                 lastPos = pos+1;
13497                             }
13498                         }
13499                         if (lastPos < info.stack.length()) {
13500                             pw.print("        ");
13501                             pw.write(info.stack, lastPos, info.stack.length()-lastPos);
13502                             pw.println();
13503                         }
13504                     }
13505                 }
13506             }
13507         }
13508
13509         if (dumpPackage == null) {
13510             pw.println();
13511             needSep = false;
13512             pw.println("  mStartedUsers:");
13513             for (int i=0; i<mStartedUsers.size(); i++) {
13514                 UserState uss = mStartedUsers.valueAt(i);
13515                 pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
13516                         pw.print(": "); uss.dump("", pw);
13517             }
13518             pw.print("  mStartedUserArray: [");
13519             for (int i=0; i<mStartedUserArray.length; i++) {
13520                 if (i > 0) pw.print(", ");
13521                 pw.print(mStartedUserArray[i]);
13522             }
13523             pw.println("]");
13524             pw.print("  mUserLru: [");
13525             for (int i=0; i<mUserLru.size(); i++) {
13526                 if (i > 0) pw.print(", ");
13527                 pw.print(mUserLru.get(i));
13528             }
13529             pw.println("]");
13530             if (dumpAll) {
13531                 pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
13532             }
13533             synchronized (mUserProfileGroupIdsSelfLocked) {
13534                 if (mUserProfileGroupIdsSelfLocked.size() > 0) {
13535                     pw.println("  mUserProfileGroupIds:");
13536                     for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
13537                         pw.print("    User #");
13538                         pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
13539                         pw.print(" -> profile #");
13540                         pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
13541                     }
13542                 }
13543             }
13544         }
13545         if (mHomeProcess != null && (dumpPackage == null
13546                 || mHomeProcess.pkgList.containsKey(dumpPackage))) {
13547             if (needSep) {
13548                 pw.println();
13549                 needSep = false;
13550             }
13551             pw.println("  mHomeProcess: " + mHomeProcess);
13552         }
13553         if (mPreviousProcess != null && (dumpPackage == null
13554                 || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
13555             if (needSep) {
13556                 pw.println();
13557                 needSep = false;
13558             }
13559             pw.println("  mPreviousProcess: " + mPreviousProcess);
13560         }
13561         if (dumpAll) {
13562             StringBuilder sb = new StringBuilder(128);
13563             sb.append("  mPreviousProcessVisibleTime: ");
13564             TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
13565             pw.println(sb);
13566         }
13567         if (mHeavyWeightProcess != null && (dumpPackage == null
13568                 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
13569             if (needSep) {
13570                 pw.println();
13571                 needSep = false;
13572             }
13573             pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
13574         }
13575         if (dumpPackage == null) {
13576             pw.println("  mConfiguration: " + mConfiguration);
13577         }
13578         if (dumpAll) {
13579             pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
13580             if (mCompatModePackages.getPackages().size() > 0) {
13581                 boolean printed = false;
13582                 for (Map.Entry<String, Integer> entry
13583                         : mCompatModePackages.getPackages().entrySet()) {
13584                     String pkg = entry.getKey();
13585                     int mode = entry.getValue();
13586                     if (dumpPackage != null && !dumpPackage.equals(pkg)) {
13587                         continue;
13588                     }
13589                     if (!printed) {
13590                         pw.println("  mScreenCompatPackages:");
13591                         printed = true;
13592                     }
13593                     pw.print("    "); pw.print(pkg); pw.print(": ");
13594                             pw.print(mode); pw.println();
13595                 }
13596             }
13597         }
13598         if (dumpPackage == null) {
13599             pw.println("  mWakefulness="
13600                     + PowerManagerInternal.wakefulnessToString(mWakefulness));
13601             pw.println("  mSleepTokens=" + mSleepTokens);
13602             pw.println("  mSleeping=" + mSleeping + " mLockScreenShown="
13603                     + lockScreenShownToString());
13604             pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
13605             if (mRunningVoice != null) {
13606                 pw.println("  mRunningVoice=" + mRunningVoice);
13607                 pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
13608             }
13609         }
13610         if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
13611                 || mOrigWaitForDebugger) {
13612             if (dumpPackage == null || dumpPackage.equals(mDebugApp)
13613                     || dumpPackage.equals(mOrigDebugApp)) {
13614                 if (needSep) {
13615                     pw.println();
13616                     needSep = false;
13617                 }
13618                 pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
13619                         + " mDebugTransient=" + mDebugTransient
13620                         + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
13621             }
13622         }
13623         if (mCurAppTimeTracker != null) {
13624             mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
13625         }
13626         if (mMemWatchProcesses.getMap().size() > 0) {
13627             pw.println("  Mem watch processes:");
13628             final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
13629                     = mMemWatchProcesses.getMap();
13630             for (int i=0; i<procs.size(); i++) {
13631                 final String proc = procs.keyAt(i);
13632                 final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
13633                 for (int j=0; j<uids.size(); j++) {
13634                     if (needSep) {
13635                         pw.println();
13636                         needSep = false;
13637                     }
13638                     StringBuilder sb = new StringBuilder();
13639                     sb.append("    ").append(proc).append('/');
13640                     UserHandle.formatUid(sb, uids.keyAt(j));
13641                     Pair<Long, String> val = uids.valueAt(j);
13642                     sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
13643                     if (val.second != null) {
13644                         sb.append(", report to ").append(val.second);
13645                     }
13646                     pw.println(sb.toString());
13647                 }
13648             }
13649             pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
13650             pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
13651             pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
13652                     pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
13653         }
13654         if (mOpenGlTraceApp != null) {
13655             if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
13656                 if (needSep) {
13657                     pw.println();
13658                     needSep = false;
13659                 }
13660                 pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
13661             }
13662         }
13663         if (mProfileApp != null || mProfileProc != null || mProfileFile != null
13664                 || mProfileFd != null) {
13665             if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
13666                 if (needSep) {
13667                     pw.println();
13668                     needSep = false;
13669                 }
13670                 pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
13671                 pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
13672                 pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
13673                         + mAutoStopProfiler);
13674                 pw.println("  mProfileType=" + mProfileType);
13675             }
13676         }
13677         if (dumpPackage == null) {
13678             if (mAlwaysFinishActivities || mController != null) {
13679                 pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
13680                         + " mController=" + mController);
13681             }
13682             if (dumpAll) {
13683                 pw.println("  Total persistent processes: " + numPers);
13684                 pw.println("  mProcessesReady=" + mProcessesReady
13685                         + " mSystemReady=" + mSystemReady
13686                         + " mBooted=" + mBooted
13687                         + " mFactoryTest=" + mFactoryTest);
13688                 pw.println("  mBooting=" + mBooting
13689                         + " mCallFinishBooting=" + mCallFinishBooting
13690                         + " mBootAnimationComplete=" + mBootAnimationComplete);
13691                 pw.print("  mLastPowerCheckRealtime=");
13692                         TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
13693                         pw.println("");
13694                 pw.print("  mLastPowerCheckUptime=");
13695                         TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
13696                         pw.println("");
13697                 pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
13698                 pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
13699                 pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
13700                 pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
13701                         + " (" + mLruProcesses.size() + " total)"
13702                         + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
13703                         + " mNumServiceProcs=" + mNumServiceProcs
13704                         + " mNewNumServiceProcs=" + mNewNumServiceProcs);
13705                 pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
13706                         + " mLastMemoryLevel" + mLastMemoryLevel
13707                         + " mLastNumProcesses" + mLastNumProcesses);
13708                 long now = SystemClock.uptimeMillis();
13709                 pw.print("  mLastIdleTime=");
13710                         TimeUtils.formatDuration(now, mLastIdleTime, pw);
13711                         pw.print(" mLowRamSinceLastIdle=");
13712                         TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
13713                         pw.println();
13714             }
13715         }
13716
13717         if (!printedAnything) {
13718             pw.println("  (nothing)");
13719         }
13720     }
13721
13722     boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
13723             int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
13724         if (mProcessesToGc.size() > 0) {
13725             boolean printed = false;
13726             long now = SystemClock.uptimeMillis();
13727             for (int i=0; i<mProcessesToGc.size(); i++) {
13728                 ProcessRecord proc = mProcessesToGc.get(i);
13729                 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
13730                     continue;
13731                 }
13732                 if (!printed) {
13733                     if (needSep) pw.println();
13734                     needSep = true;
13735                     pw.println("  Processes that are waiting to GC:");
13736                     printed = true;
13737                 }
13738                 pw.print("    Process "); pw.println(proc);
13739                 pw.print("      lowMem="); pw.print(proc.reportLowMemory);
13740                         pw.print(", last gced=");
13741                         pw.print(now-proc.lastRequestedGc);
13742                         pw.print(" ms ago, last lowMem=");
13743                         pw.print(now-proc.lastLowMemory);
13744                         pw.println(" ms ago");
13745
13746             }
13747         }
13748         return needSep;
13749     }
13750
13751     void printOomLevel(PrintWriter pw, String name, int adj) {
13752         pw.print("    ");
13753         if (adj >= 0) {
13754             pw.print(' ');
13755             if (adj < 10) pw.print(' ');
13756         } else {
13757             if (adj > -10) pw.print(' ');
13758         }
13759         pw.print(adj);
13760         pw.print(": ");
13761         pw.print(name);
13762         pw.print(" (");
13763         pw.print(mProcessList.getMemLevel(adj)/1024);
13764         pw.println(" kB)");
13765     }
13766
13767     boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13768             int opti, boolean dumpAll) {
13769         boolean needSep = false;
13770
13771         if (mLruProcesses.size() > 0) {
13772             if (needSep) pw.println();
13773             needSep = true;
13774             pw.println("  OOM levels:");
13775             printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
13776             printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
13777             printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
13778             printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
13779             printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
13780             printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
13781             printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
13782             printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
13783             printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
13784             printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
13785             printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
13786             printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
13787             printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
13788             printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
13789
13790             if (needSep) pw.println();
13791             pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
13792                     pw.print(" total, non-act at ");
13793                     pw.print(mLruProcesses.size()-mLruProcessActivityStart);
13794                     pw.print(", non-svc at ");
13795                     pw.print(mLruProcesses.size()-mLruProcessServiceStart);
13796                     pw.println("):");
13797             dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
13798             needSep = true;
13799         }
13800
13801         dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
13802
13803         pw.println();
13804         pw.println("  mHomeProcess: " + mHomeProcess);
13805         pw.println("  mPreviousProcess: " + mPreviousProcess);
13806         if (mHeavyWeightProcess != null) {
13807             pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
13808         }
13809
13810         return true;
13811     }
13812
13813     /**
13814      * There are three ways to call this:
13815      *  - no provider specified: dump all the providers
13816      *  - a flattened component name that matched an existing provider was specified as the
13817      *    first arg: dump that one provider
13818      *  - the first arg isn't the flattened component name of an existing provider:
13819      *    dump all providers whose component contains the first arg as a substring
13820      */
13821     protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13822             int opti, boolean dumpAll) {
13823         return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
13824     }
13825
13826     static class ItemMatcher {
13827         ArrayList<ComponentName> components;
13828         ArrayList<String> strings;
13829         ArrayList<Integer> objects;
13830         boolean all;
13831
13832         ItemMatcher() {
13833             all = true;
13834         }
13835
13836         void build(String name) {
13837             ComponentName componentName = ComponentName.unflattenFromString(name);
13838             if (componentName != null) {
13839                 if (components == null) {
13840                     components = new ArrayList<ComponentName>();
13841                 }
13842                 components.add(componentName);
13843                 all = false;
13844             } else {
13845                 int objectId = 0;
13846                 // Not a '/' separated full component name; maybe an object ID?
13847                 try {
13848                     objectId = Integer.parseInt(name, 16);
13849                     if (objects == null) {
13850                         objects = new ArrayList<Integer>();
13851                     }
13852                     objects.add(objectId);
13853                     all = false;
13854                 } catch (RuntimeException e) {
13855                     // Not an integer; just do string match.
13856                     if (strings == null) {
13857                         strings = new ArrayList<String>();
13858                     }
13859                     strings.add(name);
13860                     all = false;
13861                 }
13862             }
13863         }
13864
13865         int build(String[] args, int opti) {
13866             for (; opti<args.length; opti++) {
13867                 String name = args[opti];
13868                 if ("--".equals(name)) {
13869                     return opti+1;
13870                 }
13871                 build(name);
13872             }
13873             return opti;
13874         }
13875
13876         boolean match(Object object, ComponentName comp) {
13877             if (all) {
13878                 return true;
13879             }
13880             if (components != null) {
13881                 for (int i=0; i<components.size(); i++) {
13882                     if (components.get(i).equals(comp)) {
13883                         return true;
13884                     }
13885                 }
13886             }
13887             if (objects != null) {
13888                 for (int i=0; i<objects.size(); i++) {
13889                     if (System.identityHashCode(object) == objects.get(i)) {
13890                         return true;
13891                     }
13892                 }
13893             }
13894             if (strings != null) {
13895                 String flat = comp.flattenToString();
13896                 for (int i=0; i<strings.size(); i++) {
13897                     if (flat.contains(strings.get(i))) {
13898                         return true;
13899                     }
13900                 }
13901             }
13902             return false;
13903         }
13904     }
13905
13906     /**
13907      * There are three things that cmd can be:
13908      *  - a flattened component name that matches an existing activity
13909      *  - the cmd arg isn't the flattened component name of an existing activity:
13910      *    dump all activity whose component contains the cmd as a substring
13911      *  - A hex number of the ActivityRecord object instance.
13912      */
13913     protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13914             int opti, boolean dumpAll) {
13915         ArrayList<ActivityRecord> activities;
13916
13917         synchronized (this) {
13918             activities = mStackSupervisor.getDumpActivitiesLocked(name);
13919         }
13920
13921         if (activities.size() <= 0) {
13922             return false;
13923         }
13924
13925         String[] newArgs = new String[args.length - opti];
13926         System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13927
13928         TaskRecord lastTask = null;
13929         boolean needSep = false;
13930         for (int i=activities.size()-1; i>=0; i--) {
13931             ActivityRecord r = activities.get(i);
13932             if (needSep) {
13933                 pw.println();
13934             }
13935             needSep = true;
13936             synchronized (this) {
13937                 if (lastTask != r.task) {
13938                     lastTask = r.task;
13939                     pw.print("TASK "); pw.print(lastTask.affinity);
13940                             pw.print(" id="); pw.println(lastTask.taskId);
13941                     if (dumpAll) {
13942                         lastTask.dump(pw, "  ");
13943                     }
13944                 }
13945             }
13946             dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
13947         }
13948         return true;
13949     }
13950
13951     /**
13952      * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
13953      * there is a thread associated with the activity.
13954      */
13955     private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
13956             final ActivityRecord r, String[] args, boolean dumpAll) {
13957         String innerPrefix = prefix + "  ";
13958         synchronized (this) {
13959             pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
13960                     pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
13961                     pw.print(" pid=");
13962                     if (r.app != null) pw.println(r.app.pid);
13963                     else pw.println("(not running)");
13964             if (dumpAll) {
13965                 r.dump(pw, innerPrefix);
13966             }
13967         }
13968         if (r.app != null && r.app.thread != null) {
13969             // flush anything that is already in the PrintWriter since the thread is going
13970             // to write to the file descriptor directly
13971             pw.flush();
13972             try {
13973                 TransferPipe tp = new TransferPipe();
13974                 try {
13975                     r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
13976                             r.appToken, innerPrefix, args);
13977                     tp.go(fd);
13978                 } finally {
13979                     tp.kill();
13980                 }
13981             } catch (IOException e) {
13982                 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
13983             } catch (RemoteException e) {
13984                 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
13985             }
13986         }
13987     }
13988
13989     void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13990             int opti, boolean dumpAll, String dumpPackage) {
13991         boolean needSep = false;
13992         boolean onlyHistory = false;
13993         boolean printedAnything = false;
13994
13995         if ("history".equals(dumpPackage)) {
13996             if (opti < args.length && "-s".equals(args[opti])) {
13997                 dumpAll = false;
13998             }
13999             onlyHistory = true;
14000             dumpPackage = null;
14001         }
14002
14003         pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
14004         if (!onlyHistory && dumpAll) {
14005             if (mRegisteredReceivers.size() > 0) {
14006                 boolean printed = false;
14007                 Iterator it = mRegisteredReceivers.values().iterator();
14008                 while (it.hasNext()) {
14009                     ReceiverList r = (ReceiverList)it.next();
14010                     if (dumpPackage != null && (r.app == null ||
14011                             !dumpPackage.equals(r.app.info.packageName))) {
14012                         continue;
14013                     }
14014                     if (!printed) {
14015                         pw.println("  Registered Receivers:");
14016                         needSep = true;
14017                         printed = true;
14018                         printedAnything = true;
14019                     }
14020                     pw.print("  * "); pw.println(r);
14021                     r.dump(pw, "    ");
14022                 }
14023             }
14024
14025             if (mReceiverResolver.dump(pw, needSep ?
14026                     "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
14027                     "    ", dumpPackage, false, false)) {
14028                 needSep = true;
14029                 printedAnything = true;
14030             }
14031         }
14032
14033         for (BroadcastQueue q : mBroadcastQueues) {
14034             needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
14035             printedAnything |= needSep;
14036         }
14037
14038         needSep = true;
14039
14040         if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
14041             for (int user=0; user<mStickyBroadcasts.size(); user++) {
14042                 if (needSep) {
14043                     pw.println();
14044                 }
14045                 needSep = true;
14046                 printedAnything = true;
14047                 pw.print("  Sticky broadcasts for user ");
14048                         pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
14049                 StringBuilder sb = new StringBuilder(128);
14050                 for (Map.Entry<String, ArrayList<Intent>> ent
14051                         : mStickyBroadcasts.valueAt(user).entrySet()) {
14052                     pw.print("  * Sticky action "); pw.print(ent.getKey());
14053                     if (dumpAll) {
14054                         pw.println(":");
14055                         ArrayList<Intent> intents = ent.getValue();
14056                         final int N = intents.size();
14057                         for (int i=0; i<N; i++) {
14058                             sb.setLength(0);
14059                             sb.append("    Intent: ");
14060                             intents.get(i).toShortString(sb, false, true, false, false);
14061                             pw.println(sb.toString());
14062                             Bundle bundle = intents.get(i).getExtras();
14063                             if (bundle != null) {
14064                                 pw.print("      ");
14065                                 pw.println(bundle.toString());
14066                             }
14067                         }
14068                     } else {
14069                         pw.println("");
14070                     }
14071                 }
14072             }
14073         }
14074
14075         if (!onlyHistory && dumpAll) {
14076             pw.println();
14077             for (BroadcastQueue queue : mBroadcastQueues) {
14078                 pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
14079                         + queue.mBroadcastsScheduled);
14080             }
14081             pw.println("  mHandler:");
14082             mHandler.dump(new PrintWriterPrinter(pw), "    ");
14083             needSep = true;
14084             printedAnything = true;
14085         }
14086
14087         if (!printedAnything) {
14088             pw.println("  (nothing)");
14089         }
14090     }
14091
14092     void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14093             int opti, boolean dumpAll, String dumpPackage) {
14094         boolean needSep;
14095         boolean printedAnything = false;
14096
14097         ItemMatcher matcher = new ItemMatcher();
14098         matcher.build(args, opti);
14099
14100         pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
14101
14102         needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
14103         printedAnything |= needSep;
14104
14105         if (mLaunchingProviders.size() > 0) {
14106             boolean printed = false;
14107             for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
14108                 ContentProviderRecord r = mLaunchingProviders.get(i);
14109                 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
14110                     continue;
14111                 }
14112                 if (!printed) {
14113                     if (needSep) pw.println();
14114                     needSep = true;
14115                     pw.println("  Launching content providers:");
14116                     printed = true;
14117                     printedAnything = true;
14118                 }
14119                 pw.print("  Launching #"); pw.print(i); pw.print(": ");
14120                         pw.println(r);
14121             }
14122         }
14123
14124         if (!printedAnything) {
14125             pw.println("  (nothing)");
14126         }
14127     }
14128
14129     void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14130             int opti, boolean dumpAll, String dumpPackage) {
14131         boolean needSep = false;
14132         boolean printedAnything = false;
14133
14134         pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
14135
14136         if (mGrantedUriPermissions.size() > 0) {
14137             boolean printed = false;
14138             int dumpUid = -2;
14139             if (dumpPackage != null) {
14140                 try {
14141                     dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
14142                 } catch (NameNotFoundException e) {
14143                     dumpUid = -1;
14144                 }
14145             }
14146             for (int i=0; i<mGrantedUriPermissions.size(); i++) {
14147                 int uid = mGrantedUriPermissions.keyAt(i);
14148                 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
14149                     continue;
14150                 }
14151                 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
14152                 if (!printed) {
14153                     if (needSep) pw.println();
14154                     needSep = true;
14155                     pw.println("  Granted Uri Permissions:");
14156                     printed = true;
14157                     printedAnything = true;
14158                 }
14159                 pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
14160                 for (UriPermission perm : perms.values()) {
14161                     pw.print("    "); pw.println(perm);
14162                     if (dumpAll) {
14163                         perm.dump(pw, "      ");
14164                     }
14165                 }
14166             }
14167         }
14168
14169         if (!printedAnything) {
14170             pw.println("  (nothing)");
14171         }
14172     }
14173
14174     void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14175             int opti, boolean dumpAll, String dumpPackage) {
14176         boolean printed = false;
14177
14178         pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
14179
14180         if (mIntentSenderRecords.size() > 0) {
14181             Iterator<WeakReference<PendingIntentRecord>> it
14182                     = mIntentSenderRecords.values().iterator();
14183             while (it.hasNext()) {
14184                 WeakReference<PendingIntentRecord> ref = it.next();
14185                 PendingIntentRecord rec = ref != null ? ref.get(): null;
14186                 if (dumpPackage != null && (rec == null
14187                         || !dumpPackage.equals(rec.key.packageName))) {
14188                     continue;
14189                 }
14190                 printed = true;
14191                 if (rec != null) {
14192                     pw.print("  * "); pw.println(rec);
14193                     if (dumpAll) {
14194                         rec.dump(pw, "    ");
14195                     }
14196                 } else {
14197                     pw.print("  * "); pw.println(ref);
14198                 }
14199             }
14200         }
14201
14202         if (!printed) {
14203             pw.println("  (nothing)");
14204         }
14205     }
14206
14207     private static final int dumpProcessList(PrintWriter pw,
14208             ActivityManagerService service, List list,
14209             String prefix, String normalLabel, String persistentLabel,
14210             String dumpPackage) {
14211         int numPers = 0;
14212         final int N = list.size()-1;
14213         for (int i=N; i>=0; i--) {
14214             ProcessRecord r = (ProcessRecord)list.get(i);
14215             if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
14216                 continue;
14217             }
14218             pw.println(String.format("%s%s #%2d: %s",
14219                     prefix, (r.persistent ? persistentLabel : normalLabel),
14220                     i, r.toString()));
14221             if (r.persistent) {
14222                 numPers++;
14223             }
14224         }
14225         return numPers;
14226     }
14227
14228     private static final boolean dumpProcessOomList(PrintWriter pw,
14229             ActivityManagerService service, List<ProcessRecord> origList,
14230             String prefix, String normalLabel, String persistentLabel,
14231             boolean inclDetails, String dumpPackage) {
14232
14233         ArrayList<Pair<ProcessRecord, Integer>> list
14234                 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
14235         for (int i=0; i<origList.size(); i++) {
14236             ProcessRecord r = origList.get(i);
14237             if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14238                 continue;
14239             }
14240             list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
14241         }
14242
14243         if (list.size() <= 0) {
14244             return false;
14245         }
14246
14247         Comparator<Pair<ProcessRecord, Integer>> comparator
14248                 = new Comparator<Pair<ProcessRecord, Integer>>() {
14249             @Override
14250             public int compare(Pair<ProcessRecord, Integer> object1,
14251                     Pair<ProcessRecord, Integer> object2) {
14252                 if (object1.first.setAdj != object2.first.setAdj) {
14253                     return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
14254                 }
14255                 if (object1.second.intValue() != object2.second.intValue()) {
14256                     return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
14257                 }
14258                 return 0;
14259             }
14260         };
14261
14262         Collections.sort(list, comparator);
14263
14264         final long curRealtime = SystemClock.elapsedRealtime();
14265         final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
14266         final long curUptime = SystemClock.uptimeMillis();
14267         final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
14268
14269         for (int i=list.size()-1; i>=0; i--) {
14270             ProcessRecord r = list.get(i).first;
14271             String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
14272             char schedGroup;
14273             switch (r.setSchedGroup) {
14274                 case Process.THREAD_GROUP_BG_NONINTERACTIVE:
14275                     schedGroup = 'B';
14276                     break;
14277                 case Process.THREAD_GROUP_DEFAULT:
14278                     schedGroup = 'F';
14279                     break;
14280                 default:
14281                     schedGroup = '?';
14282                     break;
14283             }
14284             char foreground;
14285             if (r.foregroundActivities) {
14286                 foreground = 'A';
14287             } else if (r.foregroundServices) {
14288                 foreground = 'S';
14289             } else {
14290                 foreground = ' ';
14291             }
14292             String procState = ProcessList.makeProcStateString(r.curProcState);
14293             pw.print(prefix);
14294             pw.print(r.persistent ? persistentLabel : normalLabel);
14295             pw.print(" #");
14296             int num = (origList.size()-1)-list.get(i).second;
14297             if (num < 10) pw.print(' ');
14298             pw.print(num);
14299             pw.print(": ");
14300             pw.print(oomAdj);
14301             pw.print(' ');
14302             pw.print(schedGroup);
14303             pw.print('/');
14304             pw.print(foreground);
14305             pw.print('/');
14306             pw.print(procState);
14307             pw.print(" trm:");
14308             if (r.trimMemoryLevel < 10) pw.print(' ');
14309             pw.print(r.trimMemoryLevel);
14310             pw.print(' ');
14311             pw.print(r.toShortString());
14312             pw.print(" (");
14313             pw.print(r.adjType);
14314             pw.println(')');
14315             if (r.adjSource != null || r.adjTarget != null) {
14316                 pw.print(prefix);
14317                 pw.print("    ");
14318                 if (r.adjTarget instanceof ComponentName) {
14319                     pw.print(((ComponentName)r.adjTarget).flattenToShortString());
14320                 } else if (r.adjTarget != null) {
14321                     pw.print(r.adjTarget.toString());
14322                 } else {
14323                     pw.print("{null}");
14324                 }
14325                 pw.print("<=");
14326                 if (r.adjSource instanceof ProcessRecord) {
14327                     pw.print("Proc{");
14328                     pw.print(((ProcessRecord)r.adjSource).toShortString());
14329                     pw.println("}");
14330                 } else if (r.adjSource != null) {
14331                     pw.println(r.adjSource.toString());
14332                 } else {
14333                     pw.println("{null}");
14334                 }
14335             }
14336             if (inclDetails) {
14337                 pw.print(prefix);
14338                 pw.print("    ");
14339                 pw.print("oom: max="); pw.print(r.maxAdj);
14340                 pw.print(" curRaw="); pw.print(r.curRawAdj);
14341                 pw.print(" setRaw="); pw.print(r.setRawAdj);
14342                 pw.print(" cur="); pw.print(r.curAdj);
14343                 pw.print(" set="); pw.println(r.setAdj);
14344                 pw.print(prefix);
14345                 pw.print("    ");
14346                 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
14347                 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
14348                 pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
14349                 pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
14350                 pw.println();
14351                 pw.print(prefix);
14352                 pw.print("    ");
14353                 pw.print("cached="); pw.print(r.cached);
14354                 pw.print(" empty="); pw.print(r.empty);
14355                 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
14356
14357                 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
14358                     if (r.lastWakeTime != 0) {
14359                         long wtime;
14360                         BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
14361                         synchronized (stats) {
14362                             wtime = stats.getProcessWakeTime(r.info.uid,
14363                                     r.pid, curRealtime);
14364                         }
14365                         long timeUsed = wtime - r.lastWakeTime;
14366                         pw.print(prefix);
14367                         pw.print("    ");
14368                         pw.print("keep awake over ");
14369                         TimeUtils.formatDuration(realtimeSince, pw);
14370                         pw.print(" used ");
14371                         TimeUtils.formatDuration(timeUsed, pw);
14372                         pw.print(" (");
14373                         pw.print((timeUsed*100)/realtimeSince);
14374                         pw.println("%)");
14375                     }
14376                     if (r.lastCpuTime != 0) {
14377                         long timeUsed = r.curCpuTime - r.lastCpuTime;
14378                         pw.print(prefix);
14379                         pw.print("    ");
14380                         pw.print("run cpu over ");
14381                         TimeUtils.formatDuration(uptimeSince, pw);
14382                         pw.print(" used ");
14383                         TimeUtils.formatDuration(timeUsed, pw);
14384                         pw.print(" (");
14385                         pw.print((timeUsed*100)/uptimeSince);
14386                         pw.println("%)");
14387                     }
14388                 }
14389             }
14390         }
14391         return true;
14392     }
14393
14394     ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
14395             String[] args) {
14396         ArrayList<ProcessRecord> procs;
14397         synchronized (this) {
14398             if (args != null && args.length > start
14399                     && args[start].charAt(0) != '-') {
14400                 procs = new ArrayList<ProcessRecord>();
14401                 int pid = -1;
14402                 try {
14403                     pid = Integer.parseInt(args[start]);
14404                 } catch (NumberFormatException e) {
14405                 }
14406                 for (int i=mLruProcesses.size()-1; i>=0; i--) {
14407                     ProcessRecord proc = mLruProcesses.get(i);
14408                     if (proc.pid == pid) {
14409                         procs.add(proc);
14410                     } else if (allPkgs && proc.pkgList != null
14411                             && proc.pkgList.containsKey(args[start])) {
14412                         procs.add(proc);
14413                     } else if (proc.processName.equals(args[start])) {
14414                         procs.add(proc);
14415                     }
14416                 }
14417                 if (procs.size() <= 0) {
14418                     return null;
14419                 }
14420             } else {
14421                 procs = new ArrayList<ProcessRecord>(mLruProcesses);
14422             }
14423         }
14424         return procs;
14425     }
14426
14427     final void dumpGraphicsHardwareUsage(FileDescriptor fd,
14428             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         long uptime = SystemClock.uptimeMillis();
14436         long realtime = SystemClock.elapsedRealtime();
14437         pw.println("Applications Graphics Acceleration Info:");
14438         pw.println("Uptime: " + uptime + " Realtime: " + realtime);
14439
14440         for (int i = procs.size() - 1 ; i >= 0 ; i--) {
14441             ProcessRecord r = procs.get(i);
14442             if (r.thread != null) {
14443                 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
14444                 pw.flush();
14445                 try {
14446                     TransferPipe tp = new TransferPipe();
14447                     try {
14448                         r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
14449                         tp.go(fd);
14450                     } finally {
14451                         tp.kill();
14452                     }
14453                 } catch (IOException e) {
14454                     pw.println("Failure while dumping the app: " + r);
14455                     pw.flush();
14456                 } catch (RemoteException e) {
14457                     pw.println("Got a RemoteException while dumping the app " + r);
14458                     pw.flush();
14459                 }
14460             }
14461         }
14462     }
14463
14464     final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
14465         ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
14466         if (procs == null) {
14467             pw.println("No process found for: " + args[0]);
14468             return;
14469         }
14470
14471         pw.println("Applications Database Info:");
14472
14473         for (int i = procs.size() - 1 ; i >= 0 ; i--) {
14474             ProcessRecord r = procs.get(i);
14475             if (r.thread != null) {
14476                 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
14477                 pw.flush();
14478                 try {
14479                     TransferPipe tp = new TransferPipe();
14480                     try {
14481                         r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
14482                         tp.go(fd);
14483                     } finally {
14484                         tp.kill();
14485                     }
14486                 } catch (IOException e) {
14487                     pw.println("Failure while dumping the app: " + r);
14488                     pw.flush();
14489                 } catch (RemoteException e) {
14490                     pw.println("Got a RemoteException while dumping the app " + r);
14491                     pw.flush();
14492                 }
14493             }
14494         }
14495     }
14496
14497     final static class MemItem {
14498         final boolean isProc;
14499         final String label;
14500         final String shortLabel;
14501         final long pss;
14502         final int id;
14503         final boolean hasActivities;
14504         ArrayList<MemItem> subitems;
14505
14506         public MemItem(String _label, String _shortLabel, long _pss, int _id,
14507                 boolean _hasActivities) {
14508             isProc = true;
14509             label = _label;
14510             shortLabel = _shortLabel;
14511             pss = _pss;
14512             id = _id;
14513             hasActivities = _hasActivities;
14514         }
14515
14516         public MemItem(String _label, String _shortLabel, long _pss, int _id) {
14517             isProc = false;
14518             label = _label;
14519             shortLabel = _shortLabel;
14520             pss = _pss;
14521             id = _id;
14522             hasActivities = false;
14523         }
14524     }
14525
14526     static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
14527             ArrayList<MemItem> items, boolean sort, boolean isCompact) {
14528         if (sort && !isCompact) {
14529             Collections.sort(items, new Comparator<MemItem>() {
14530                 @Override
14531                 public int compare(MemItem lhs, MemItem rhs) {
14532                     if (lhs.pss < rhs.pss) {
14533                         return 1;
14534                     } else if (lhs.pss > rhs.pss) {
14535                         return -1;
14536                     }
14537                     return 0;
14538                 }
14539             });
14540         }
14541
14542         for (int i=0; i<items.size(); i++) {
14543             MemItem mi = items.get(i);
14544             if (!isCompact) {
14545                 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
14546             } else if (mi.isProc) {
14547                 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
14548                 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
14549                 pw.println(mi.hasActivities ? ",a" : ",e");
14550             } else {
14551                 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
14552                 pw.println(mi.pss);
14553             }
14554             if (mi.subitems != null) {
14555                 dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
14556                         true, isCompact);
14557             }
14558         }
14559     }
14560
14561     // These are in KB.
14562     static final long[] DUMP_MEM_BUCKETS = new long[] {
14563         5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
14564         120*1024, 160*1024, 200*1024,
14565         250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
14566         1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
14567     };
14568
14569     static final void appendMemBucket(StringBuilder out, long memKB, String label,
14570             boolean stackLike) {
14571         int start = label.lastIndexOf('.');
14572         if (start >= 0) start++;
14573         else start = 0;
14574         int end = label.length();
14575         for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
14576             if (DUMP_MEM_BUCKETS[i] >= memKB) {
14577                 long bucket = DUMP_MEM_BUCKETS[i]/1024;
14578                 out.append(bucket);
14579                 out.append(stackLike ? "MB." : "MB ");
14580                 out.append(label, start, end);
14581                 return;
14582             }
14583         }
14584         out.append(memKB/1024);
14585         out.append(stackLike ? "MB." : "MB ");
14586         out.append(label, start, end);
14587     }
14588
14589     static final int[] DUMP_MEM_OOM_ADJ = new int[] {
14590             ProcessList.NATIVE_ADJ,
14591             ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
14592             ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
14593             ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
14594             ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
14595             ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
14596             ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
14597     };
14598     static final String[] DUMP_MEM_OOM_LABEL = new String[] {
14599             "Native",
14600             "System", "Persistent", "Persistent Service", "Foreground",
14601             "Visible", "Perceptible",
14602             "Heavy Weight", "Backup",
14603             "A Services", "Home",
14604             "Previous", "B Services", "Cached"
14605     };
14606     static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
14607             "native",
14608             "sys", "pers", "persvc", "fore",
14609             "vis", "percept",
14610             "heavy", "backup",
14611             "servicea", "home",
14612             "prev", "serviceb", "cached"
14613     };
14614
14615     private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
14616             long realtime, boolean isCheckinRequest, boolean isCompact) {
14617         if (isCheckinRequest || isCompact) {
14618             // short checkin version
14619             pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
14620         } else {
14621             pw.println("Applications Memory Usage (kB):");
14622             pw.println("Uptime: " + uptime + " Realtime: " + realtime);
14623         }
14624     }
14625
14626     private static final int KSM_SHARED = 0;
14627     private static final int KSM_SHARING = 1;
14628     private static final int KSM_UNSHARED = 2;
14629     private static final int KSM_VOLATILE = 3;
14630
14631     private final long[] getKsmInfo() {
14632         long[] longOut = new long[4];
14633         final int[] SINGLE_LONG_FORMAT = new int[] {
14634             Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
14635         };
14636         long[] longTmp = new long[1];
14637         Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
14638                 SINGLE_LONG_FORMAT, null, longTmp, null);
14639         longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14640         longTmp[0] = 0;
14641         Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
14642                 SINGLE_LONG_FORMAT, null, longTmp, null);
14643         longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14644         longTmp[0] = 0;
14645         Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
14646                 SINGLE_LONG_FORMAT, null, longTmp, null);
14647         longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14648         longTmp[0] = 0;
14649         Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
14650                 SINGLE_LONG_FORMAT, null, longTmp, null);
14651         longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14652         return longOut;
14653     }
14654
14655     final void dumpApplicationMemoryUsage(FileDescriptor fd,
14656             PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
14657         boolean dumpDetails = false;
14658         boolean dumpFullDetails = false;
14659         boolean dumpDalvik = false;
14660         boolean dumpSummaryOnly = false;
14661         boolean oomOnly = false;
14662         boolean isCompact = false;
14663         boolean localOnly = false;
14664         boolean packages = false;
14665
14666         int opti = 0;
14667         while (opti < args.length) {
14668             String opt = args[opti];
14669             if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
14670                 break;
14671             }
14672             opti++;
14673             if ("-a".equals(opt)) {
14674                 dumpDetails = true;
14675                 dumpFullDetails = true;
14676                 dumpDalvik = true;
14677             } else if ("-d".equals(opt)) {
14678                 dumpDalvik = true;
14679             } else if ("-c".equals(opt)) {
14680                 isCompact = true;
14681             } else if ("-s".equals(opt)) {
14682                 dumpDetails = true;
14683                 dumpSummaryOnly = true;
14684             } else if ("--oom".equals(opt)) {
14685                 oomOnly = true;
14686             } else if ("--local".equals(opt)) {
14687                 localOnly = true;
14688             } else if ("--package".equals(opt)) {
14689                 packages = true;
14690             } else if ("-h".equals(opt)) {
14691                 pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
14692                 pw.println("  -a: include all available information for each process.");
14693                 pw.println("  -d: include dalvik details.");
14694                 pw.println("  -c: dump in a compact machine-parseable representation.");
14695                 pw.println("  -s: dump only summary of application memory usage.");
14696                 pw.println("  --oom: only show processes organized by oom adj.");
14697                 pw.println("  --local: only collect details locally, don't call process.");
14698                 pw.println("  --package: interpret process arg as package, dumping all");
14699                 pw.println("             processes that have loaded that package.");
14700                 pw.println("If [process] is specified it can be the name or ");
14701                 pw.println("pid of a specific process to dump.");
14702                 return;
14703             } else {
14704                 pw.println("Unknown argument: " + opt + "; use -h for help");
14705             }
14706         }
14707
14708         final boolean isCheckinRequest = scanArgs(args, "--checkin");
14709         long uptime = SystemClock.uptimeMillis();
14710         long realtime = SystemClock.elapsedRealtime();
14711         final long[] tmpLong = new long[1];
14712
14713         ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
14714         if (procs == null) {
14715             // No Java processes.  Maybe they want to print a native process.
14716             if (args != null && args.length > opti
14717                     && args[opti].charAt(0) != '-') {
14718                 ArrayList<ProcessCpuTracker.Stats> nativeProcs
14719                         = new ArrayList<ProcessCpuTracker.Stats>();
14720                 updateCpuStatsNow();
14721                 int findPid = -1;
14722                 try {
14723                     findPid = Integer.parseInt(args[opti]);
14724                 } catch (NumberFormatException e) {
14725                 }
14726                 synchronized (mProcessCpuTracker) {
14727                     final int N = mProcessCpuTracker.countStats();
14728                     for (int i=0; i<N; i++) {
14729                         ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14730                         if (st.pid == findPid || (st.baseName != null
14731                                 && st.baseName.equals(args[opti]))) {
14732                             nativeProcs.add(st);
14733                         }
14734                     }
14735                 }
14736                 if (nativeProcs.size() > 0) {
14737                     dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
14738                             isCompact);
14739                     Debug.MemoryInfo mi = null;
14740                     for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
14741                         final ProcessCpuTracker.Stats r = nativeProcs.get(i);
14742                         final int pid = r.pid;
14743                         if (!isCheckinRequest && dumpDetails) {
14744                             pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
14745                         }
14746                         if (mi == null) {
14747                             mi = new Debug.MemoryInfo();
14748                         }
14749                         if (dumpDetails || (!brief && !oomOnly)) {
14750                             Debug.getMemoryInfo(pid, mi);
14751                         } else {
14752                             mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
14753                             mi.dalvikPrivateDirty = (int)tmpLong[0];
14754                         }
14755                         ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
14756                                 dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
14757                         if (isCheckinRequest) {
14758                             pw.println();
14759                         }
14760                     }
14761                     return;
14762                 }
14763             }
14764             pw.println("No process found for: " + args[opti]);
14765             return;
14766         }
14767
14768         if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
14769             dumpDetails = true;
14770         }
14771
14772         dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
14773
14774         String[] innerArgs = new String[args.length-opti];
14775         System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
14776
14777         ArrayList<MemItem> procMems = new ArrayList<MemItem>();
14778         final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
14779         long nativePss = 0;
14780         long dalvikPss = 0;
14781         long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
14782                 EmptyArray.LONG;
14783         long otherPss = 0;
14784         long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
14785
14786         long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
14787         ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
14788                 new ArrayList[DUMP_MEM_OOM_LABEL.length];
14789
14790         long totalPss = 0;
14791         long cachedPss = 0;
14792
14793         Debug.MemoryInfo mi = null;
14794         for (int i = procs.size() - 1 ; i >= 0 ; i--) {
14795             final ProcessRecord r = procs.get(i);
14796             final IApplicationThread thread;
14797             final int pid;
14798             final int oomAdj;
14799             final boolean hasActivities;
14800             synchronized (this) {
14801                 thread = r.thread;
14802                 pid = r.pid;
14803                 oomAdj = r.getSetAdjWithServices();
14804                 hasActivities = r.activities.size() > 0;
14805             }
14806             if (thread != null) {
14807                 if (!isCheckinRequest && dumpDetails) {
14808                     pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
14809                 }
14810                 if (mi == null) {
14811                     mi = new Debug.MemoryInfo();
14812                 }
14813                 if (dumpDetails || (!brief && !oomOnly)) {
14814                     Debug.getMemoryInfo(pid, mi);
14815                 } else {
14816                     mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
14817                     mi.dalvikPrivateDirty = (int)tmpLong[0];
14818                 }
14819                 if (dumpDetails) {
14820                     if (localOnly) {
14821                         ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
14822                                 dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
14823                         if (isCheckinRequest) {
14824                             pw.println();
14825                         }
14826                     } else {
14827                         try {
14828                             pw.flush();
14829                             thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
14830                                     dumpDalvik, dumpSummaryOnly, innerArgs);
14831                         } catch (RemoteException e) {
14832                             if (!isCheckinRequest) {
14833                                 pw.println("Got RemoteException!");
14834                                 pw.flush();
14835                             }
14836                         }
14837                     }
14838                 }
14839
14840                 final long myTotalPss = mi.getTotalPss();
14841                 final long myTotalUss = mi.getTotalUss();
14842
14843                 synchronized (this) {
14844                     if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
14845                         // Record this for posterity if the process has been stable.
14846                         r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
14847                     }
14848                 }
14849
14850                 if (!isCheckinRequest && mi != null) {
14851                     totalPss += myTotalPss;
14852                     MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
14853                             (hasActivities ? " / activities)" : ")"),
14854                             r.processName, myTotalPss, pid, hasActivities);
14855                     procMems.add(pssItem);
14856                     procMemsMap.put(pid, pssItem);
14857
14858                     nativePss += mi.nativePss;
14859                     dalvikPss += mi.dalvikPss;
14860                     for (int j=0; j<dalvikSubitemPss.length; j++) {
14861                         dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
14862                     }
14863                     otherPss += mi.otherPss;
14864                     for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14865                         long mem = mi.getOtherPss(j);
14866                         miscPss[j] += mem;
14867                         otherPss -= mem;
14868                     }
14869
14870                     if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
14871                         cachedPss += myTotalPss;
14872                     }
14873
14874                     for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
14875                         if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
14876                                 || oomIndex == (oomPss.length-1)) {
14877                             oomPss[oomIndex] += myTotalPss;
14878                             if (oomProcs[oomIndex] == null) {
14879                                 oomProcs[oomIndex] = new ArrayList<MemItem>();
14880                             }
14881                             oomProcs[oomIndex].add(pssItem);
14882                             break;
14883                         }
14884                     }
14885                 }
14886             }
14887         }
14888
14889         long nativeProcTotalPss = 0;
14890
14891         if (!isCheckinRequest && procs.size() > 1 && !packages) {
14892             // If we are showing aggregations, also look for native processes to
14893             // include so that our aggregations are more accurate.
14894             updateCpuStatsNow();
14895             mi = null;
14896             synchronized (mProcessCpuTracker) {
14897                 final int N = mProcessCpuTracker.countStats();
14898                 for (int i=0; i<N; i++) {
14899                     ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14900                     if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
14901                         if (mi == null) {
14902                             mi = new Debug.MemoryInfo();
14903                         }
14904                         if (!brief && !oomOnly) {
14905                             Debug.getMemoryInfo(st.pid, mi);
14906                         } else {
14907                             mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
14908                             mi.nativePrivateDirty = (int)tmpLong[0];
14909                         }
14910
14911                         final long myTotalPss = mi.getTotalPss();
14912                         totalPss += myTotalPss;
14913                         nativeProcTotalPss += myTotalPss;
14914
14915                         MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
14916                                 st.name, myTotalPss, st.pid, false);
14917                         procMems.add(pssItem);
14918
14919                         nativePss += mi.nativePss;
14920                         dalvikPss += mi.dalvikPss;
14921                         for (int j=0; j<dalvikSubitemPss.length; j++) {
14922                             dalvikSubitemPss[j] += mi.getOtherPss(
14923                                     Debug.MemoryInfo.NUM_OTHER_STATS + j);
14924                         }
14925                         otherPss += mi.otherPss;
14926                         for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14927                             long mem = mi.getOtherPss(j);
14928                             miscPss[j] += mem;
14929                             otherPss -= mem;
14930                         }
14931                         oomPss[0] += myTotalPss;
14932                         if (oomProcs[0] == null) {
14933                             oomProcs[0] = new ArrayList<MemItem>();
14934                         }
14935                         oomProcs[0].add(pssItem);
14936                     }
14937                 }
14938             }
14939
14940             ArrayList<MemItem> catMems = new ArrayList<MemItem>();
14941
14942             catMems.add(new MemItem("Native", "Native", nativePss, -1));
14943             final MemItem dalvikItem = new MemItem("Dalvik", "Dalvik", dalvikPss, -2);
14944             if (dalvikSubitemPss.length > 0) {
14945                 dalvikItem.subitems = new ArrayList<MemItem>();
14946                 for (int j=0; j<dalvikSubitemPss.length; j++) {
14947                     final String name = Debug.MemoryInfo.getOtherLabel(
14948                             Debug.MemoryInfo.NUM_OTHER_STATS + j);
14949                     dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j], j));
14950                 }
14951             }
14952             catMems.add(dalvikItem);
14953             catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
14954             for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14955                 String label = Debug.MemoryInfo.getOtherLabel(j);
14956                 catMems.add(new MemItem(label, label, miscPss[j], j));
14957             }
14958
14959             ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
14960             for (int j=0; j<oomPss.length; j++) {
14961                 if (oomPss[j] != 0) {
14962                     String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
14963                             : DUMP_MEM_OOM_LABEL[j];
14964                     MemItem item = new MemItem(label, label, oomPss[j],
14965                             DUMP_MEM_OOM_ADJ[j]);
14966                     item.subitems = oomProcs[j];
14967                     oomMems.add(item);
14968                 }
14969             }
14970
14971             if (!brief && !oomOnly && !isCompact) {
14972                 pw.println();
14973                 pw.println("Total PSS by process:");
14974                 dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
14975                 pw.println();
14976             }
14977             if (!isCompact) {
14978                 pw.println("Total PSS by OOM adjustment:");
14979             }
14980             dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
14981             if (!brief && !oomOnly) {
14982                 PrintWriter out = categoryPw != null ? categoryPw : pw;
14983                 if (!isCompact) {
14984                     out.println();
14985                     out.println("Total PSS by category:");
14986                 }
14987                 dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
14988             }
14989             if (!isCompact) {
14990                 pw.println();
14991             }
14992             MemInfoReader memInfo = new MemInfoReader();
14993             memInfo.readMemInfo();
14994             if (nativeProcTotalPss > 0) {
14995                 synchronized (this) {
14996                     final long cachedKb = memInfo.getCachedSizeKb();
14997                     final long freeKb = memInfo.getFreeSizeKb();
14998                     final long zramKb = memInfo.getZramTotalSizeKb();
14999                     final long kernelKb = memInfo.getKernelUsedSizeKb();
15000                     EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
15001                             kernelKb*1024, nativeProcTotalPss*1024);
15002                     mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
15003                             nativeProcTotalPss);
15004                 }
15005             }
15006             if (!brief) {
15007                 if (!isCompact) {
15008                     pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
15009                     pw.print(" kB (status ");
15010                     switch (mLastMemoryLevel) {
15011                         case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
15012                             pw.println("normal)");
15013                             break;
15014                         case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
15015                             pw.println("moderate)");
15016                             break;
15017                         case ProcessStats.ADJ_MEM_FACTOR_LOW:
15018                             pw.println("low)");
15019                             break;
15020                         case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
15021                             pw.println("critical)");
15022                             break;
15023                         default:
15024                             pw.print(mLastMemoryLevel);
15025                             pw.println(")");
15026                             break;
15027                     }
15028                     pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
15029                             + memInfo.getFreeSizeKb()); pw.print(" kB (");
15030                             pw.print(cachedPss); pw.print(" cached pss + ");
15031                             pw.print(memInfo.getCachedSizeKb()); pw.print(" cached kernel + ");
15032                             pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
15033                 } else {
15034                     pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
15035                     pw.print(cachedPss + memInfo.getCachedSizeKb()
15036                             + memInfo.getFreeSizeKb()); pw.print(",");
15037                     pw.println(totalPss - cachedPss);
15038                 }
15039             }
15040             if (!isCompact) {
15041                 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
15042                         + memInfo.getKernelUsedSizeKb()); pw.print(" kB (");
15043                         pw.print(totalPss - cachedPss); pw.print(" used pss + ");
15044                         pw.print(memInfo.getKernelUsedSizeKb()); pw.print(" kernel)\n");
15045                 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
15046                         - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
15047                         - memInfo.getKernelUsedSizeKb()); pw.println(" kB");
15048             }
15049             if (!brief) {
15050                 if (memInfo.getZramTotalSizeKb() != 0) {
15051                     if (!isCompact) {
15052                         pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
15053                                 pw.print(" kB physical used for ");
15054                                 pw.print(memInfo.getSwapTotalSizeKb()
15055                                         - memInfo.getSwapFreeSizeKb());
15056                                 pw.print(" kB in swap (");
15057                                 pw.print(memInfo.getSwapTotalSizeKb());
15058                                 pw.println(" kB total swap)");
15059                     } else {
15060                         pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
15061                                 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
15062                                 pw.println(memInfo.getSwapFreeSizeKb());
15063                     }
15064                 }
15065                 final long[] ksm = getKsmInfo();
15066                 if (!isCompact) {
15067                     if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
15068                             || ksm[KSM_VOLATILE] != 0) {
15069                         pw.print("      KSM: "); pw.print(ksm[KSM_SHARING]);
15070                                 pw.print(" kB saved from shared ");
15071                                 pw.print(ksm[KSM_SHARED]); pw.println(" kB");
15072                         pw.print("           "); pw.print(ksm[KSM_UNSHARED]);
15073                                 pw.print(" kB unshared; ");
15074                                 pw.print(ksm[KSM_VOLATILE]); pw.println(" kB volatile");
15075                     }
15076                     pw.print("   Tuning: ");
15077                     pw.print(ActivityManager.staticGetMemoryClass());
15078                     pw.print(" (large ");
15079                     pw.print(ActivityManager.staticGetLargeMemoryClass());
15080                     pw.print("), oom ");
15081                     pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
15082                     pw.print(" kB");
15083                     pw.print(", restore limit ");
15084                     pw.print(mProcessList.getCachedRestoreThresholdKb());
15085                     pw.print(" kB");
15086                     if (ActivityManager.isLowRamDeviceStatic()) {
15087                         pw.print(" (low-ram)");
15088                     }
15089                     if (ActivityManager.isHighEndGfx()) {
15090                         pw.print(" (high-end-gfx)");
15091                     }
15092                     pw.println();
15093                 } else {
15094                     pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
15095                     pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
15096                     pw.print(","); pw.println(ksm[KSM_VOLATILE]);
15097                     pw.print("tuning,");
15098                     pw.print(ActivityManager.staticGetMemoryClass());
15099                     pw.print(',');
15100                     pw.print(ActivityManager.staticGetLargeMemoryClass());
15101                     pw.print(',');
15102                     pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
15103                     if (ActivityManager.isLowRamDeviceStatic()) {
15104                         pw.print(",low-ram");
15105                     }
15106                     if (ActivityManager.isHighEndGfx()) {
15107                         pw.print(",high-end-gfx");
15108                     }
15109                     pw.println();
15110                 }
15111             }
15112         }
15113     }
15114
15115     private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
15116             long memtrack, String name) {
15117         sb.append("  ");
15118         sb.append(ProcessList.makeOomAdjString(oomAdj));
15119         sb.append(' ');
15120         sb.append(ProcessList.makeProcStateString(procState));
15121         sb.append(' ');
15122         ProcessList.appendRamKb(sb, pss);
15123         sb.append(" kB: ");
15124         sb.append(name);
15125         if (memtrack > 0) {
15126             sb.append(" (");
15127             sb.append(memtrack);
15128             sb.append(" kB memtrack)");
15129         }
15130     }
15131
15132     private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
15133         appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
15134         sb.append(" (pid ");
15135         sb.append(mi.pid);
15136         sb.append(") ");
15137         sb.append(mi.adjType);
15138         sb.append('\n');
15139         if (mi.adjReason != null) {
15140             sb.append("                      ");
15141             sb.append(mi.adjReason);
15142             sb.append('\n');
15143         }
15144     }
15145
15146     void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
15147         final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
15148         for (int i=0, N=memInfos.size(); i<N; i++) {
15149             ProcessMemInfo mi = memInfos.get(i);
15150             infoMap.put(mi.pid, mi);
15151         }
15152         updateCpuStatsNow();
15153         long[] memtrackTmp = new long[1];
15154         synchronized (mProcessCpuTracker) {
15155             final int N = mProcessCpuTracker.countStats();
15156             for (int i=0; i<N; i++) {
15157                 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15158                 if (st.vsize > 0) {
15159                     long pss = Debug.getPss(st.pid, null, memtrackTmp);
15160                     if (pss > 0) {
15161                         if (infoMap.indexOfKey(st.pid) < 0) {
15162                             ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
15163                                     ProcessList.NATIVE_ADJ, -1, "native", null);
15164                             mi.pss = pss;
15165                             mi.memtrack = memtrackTmp[0];
15166                             memInfos.add(mi);
15167                         }
15168                     }
15169                 }
15170             }
15171         }
15172
15173         long totalPss = 0;
15174         long totalMemtrack = 0;
15175         for (int i=0, N=memInfos.size(); i<N; i++) {
15176             ProcessMemInfo mi = memInfos.get(i);
15177             if (mi.pss == 0) {
15178                 mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
15179                 mi.memtrack = memtrackTmp[0];
15180             }
15181             totalPss += mi.pss;
15182             totalMemtrack += mi.memtrack;
15183         }
15184         Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
15185             @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
15186                 if (lhs.oomAdj != rhs.oomAdj) {
15187                     return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
15188                 }
15189                 if (lhs.pss != rhs.pss) {
15190                     return lhs.pss < rhs.pss ? 1 : -1;
15191                 }
15192                 return 0;
15193             }
15194         });
15195
15196         StringBuilder tag = new StringBuilder(128);
15197         StringBuilder stack = new StringBuilder(128);
15198         tag.append("Low on memory -- ");
15199         appendMemBucket(tag, totalPss, "total", false);
15200         appendMemBucket(stack, totalPss, "total", true);
15201
15202         StringBuilder fullNativeBuilder = new StringBuilder(1024);
15203         StringBuilder shortNativeBuilder = new StringBuilder(1024);
15204         StringBuilder fullJavaBuilder = new StringBuilder(1024);
15205
15206         boolean firstLine = true;
15207         int lastOomAdj = Integer.MIN_VALUE;
15208         long extraNativeRam = 0;
15209         long extraNativeMemtrack = 0;
15210         long cachedPss = 0;
15211         for (int i=0, N=memInfos.size(); i<N; i++) {
15212             ProcessMemInfo mi = memInfos.get(i);
15213
15214             if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
15215                 cachedPss += mi.pss;
15216             }
15217
15218             if (mi.oomAdj != ProcessList.NATIVE_ADJ
15219                     && (mi.oomAdj < ProcessList.SERVICE_ADJ
15220                             || mi.oomAdj == ProcessList.HOME_APP_ADJ
15221                             || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
15222                 if (lastOomAdj != mi.oomAdj) {
15223                     lastOomAdj = mi.oomAdj;
15224                     if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15225                         tag.append(" / ");
15226                     }
15227                     if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
15228                         if (firstLine) {
15229                             stack.append(":");
15230                             firstLine = false;
15231                         }
15232                         stack.append("\n\t at ");
15233                     } else {
15234                         stack.append("$");
15235                     }
15236                 } else {
15237                     tag.append(" ");
15238                     stack.append("$");
15239                 }
15240                 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15241                     appendMemBucket(tag, mi.pss, mi.name, false);
15242                 }
15243                 appendMemBucket(stack, mi.pss, mi.name, true);
15244                 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
15245                         && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
15246                     stack.append("(");
15247                     for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
15248                         if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
15249                             stack.append(DUMP_MEM_OOM_LABEL[k]);
15250                             stack.append(":");
15251                             stack.append(DUMP_MEM_OOM_ADJ[k]);
15252                         }
15253                     }
15254                     stack.append(")");
15255                 }
15256             }
15257
15258             appendMemInfo(fullNativeBuilder, mi);
15259             if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
15260                 // The short form only has native processes that are >= 512K.
15261                 if (mi.pss >= 512) {
15262                     appendMemInfo(shortNativeBuilder, mi);
15263                 } else {
15264                     extraNativeRam += mi.pss;
15265                     extraNativeMemtrack += mi.memtrack;
15266                 }
15267             } else {
15268                 // Short form has all other details, but if we have collected RAM
15269                 // from smaller native processes let's dump a summary of that.
15270                 if (extraNativeRam > 0) {
15271                     appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
15272                             -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
15273                     shortNativeBuilder.append('\n');
15274                     extraNativeRam = 0;
15275                 }
15276                 appendMemInfo(fullJavaBuilder, mi);
15277             }
15278         }
15279
15280         fullJavaBuilder.append("           ");
15281         ProcessList.appendRamKb(fullJavaBuilder, totalPss);
15282         fullJavaBuilder.append(" kB: TOTAL");
15283         if (totalMemtrack > 0) {
15284             fullJavaBuilder.append(" (");
15285             fullJavaBuilder.append(totalMemtrack);
15286             fullJavaBuilder.append(" kB memtrack)");
15287         } else {
15288         }
15289         fullJavaBuilder.append("\n");
15290
15291         MemInfoReader memInfo = new MemInfoReader();
15292         memInfo.readMemInfo();
15293         final long[] infos = memInfo.getRawInfo();
15294
15295         StringBuilder memInfoBuilder = new StringBuilder(1024);
15296         Debug.getMemInfo(infos);
15297         memInfoBuilder.append("  MemInfo: ");
15298         memInfoBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
15299         memInfoBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
15300         memInfoBuilder.append(infos[Debug.MEMINFO_VM_ALLOC_USED]).append(" kB vm alloc, ");
15301         memInfoBuilder.append(infos[Debug.MEMINFO_PAGE_TABLES]).append(" kB page tables ");
15302         memInfoBuilder.append(infos[Debug.MEMINFO_KERNEL_STACK]).append(" kB kernel stack\n");
15303         memInfoBuilder.append("           ");
15304         memInfoBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
15305         memInfoBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
15306         memInfoBuilder.append(infos[Debug.MEMINFO_MAPPED]).append(" kB mapped, ");
15307         memInfoBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
15308         if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
15309             memInfoBuilder.append("  ZRAM: ");
15310             memInfoBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
15311             memInfoBuilder.append(" kB RAM, ");
15312             memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
15313             memInfoBuilder.append(" kB swap total, ");
15314             memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
15315             memInfoBuilder.append(" kB swap free\n");
15316         }
15317         final long[] ksm = getKsmInfo();
15318         if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
15319                 || ksm[KSM_VOLATILE] != 0) {
15320             memInfoBuilder.append("  KSM: "); memInfoBuilder.append(ksm[KSM_SHARING]);
15321             memInfoBuilder.append(" kB saved from shared ");
15322             memInfoBuilder.append(ksm[KSM_SHARED]); memInfoBuilder.append(" kB\n");
15323             memInfoBuilder.append("       "); memInfoBuilder.append(ksm[KSM_UNSHARED]);
15324             memInfoBuilder.append(" kB unshared; ");
15325             memInfoBuilder.append(ksm[KSM_VOLATILE]); memInfoBuilder.append(" kB volatile\n");
15326         }
15327         memInfoBuilder.append("  Free RAM: ");
15328         memInfoBuilder.append(cachedPss + memInfo.getCachedSizeKb()
15329                 + memInfo.getFreeSizeKb());
15330         memInfoBuilder.append(" kB\n");
15331         memInfoBuilder.append("  Used RAM: ");
15332         memInfoBuilder.append(totalPss - cachedPss + memInfo.getKernelUsedSizeKb());
15333         memInfoBuilder.append(" kB\n");
15334         memInfoBuilder.append("  Lost RAM: ");
15335         memInfoBuilder.append(memInfo.getTotalSizeKb()
15336                 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
15337                 - memInfo.getKernelUsedSizeKb());
15338         memInfoBuilder.append(" kB\n");
15339         Slog.i(TAG, "Low on memory:");
15340         Slog.i(TAG, shortNativeBuilder.toString());
15341         Slog.i(TAG, fullJavaBuilder.toString());
15342         Slog.i(TAG, memInfoBuilder.toString());
15343
15344         StringBuilder dropBuilder = new StringBuilder(1024);
15345         /*
15346         StringWriter oomSw = new StringWriter();
15347         PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
15348         StringWriter catSw = new StringWriter();
15349         PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
15350         String[] emptyArgs = new String[] { };
15351         dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
15352         oomPw.flush();
15353         String oomString = oomSw.toString();
15354         */
15355         dropBuilder.append("Low on memory:");
15356         dropBuilder.append(stack);
15357         dropBuilder.append('\n');
15358         dropBuilder.append(fullNativeBuilder);
15359         dropBuilder.append(fullJavaBuilder);
15360         dropBuilder.append('\n');
15361         dropBuilder.append(memInfoBuilder);
15362         dropBuilder.append('\n');
15363         /*
15364         dropBuilder.append(oomString);
15365         dropBuilder.append('\n');
15366         */
15367         StringWriter catSw = new StringWriter();
15368         synchronized (ActivityManagerService.this) {
15369             PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
15370             String[] emptyArgs = new String[] { };
15371             catPw.println();
15372             dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
15373             catPw.println();
15374             mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
15375                     false, false, null);
15376             catPw.println();
15377             dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
15378             catPw.flush();
15379         }
15380         dropBuilder.append(catSw.toString());
15381         addErrorToDropBox("lowmem", null, "system_server", null,
15382                 null, tag.toString(), dropBuilder.toString(), null, null);
15383         //Slog.i(TAG, "Sent to dropbox:");
15384         //Slog.i(TAG, dropBuilder.toString());
15385         synchronized (ActivityManagerService.this) {
15386             long now = SystemClock.uptimeMillis();
15387             if (mLastMemUsageReportTime < now) {
15388                 mLastMemUsageReportTime = now;
15389             }
15390         }
15391     }
15392
15393     /**
15394      * Searches array of arguments for the specified string
15395      * @param args array of argument strings
15396      * @param value value to search for
15397      * @return true if the value is contained in the array
15398      */
15399     private static boolean scanArgs(String[] args, String value) {
15400         if (args != null) {
15401             for (String arg : args) {
15402                 if (value.equals(arg)) {
15403                     return true;
15404                 }
15405             }
15406         }
15407         return false;
15408     }
15409
15410     private final boolean removeDyingProviderLocked(ProcessRecord proc,
15411             ContentProviderRecord cpr, boolean always) {
15412         final boolean inLaunching = mLaunchingProviders.contains(cpr);
15413
15414         if (!inLaunching || always) {
15415             synchronized (cpr) {
15416                 cpr.launchingApp = null;
15417                 cpr.notifyAll();
15418             }
15419             mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
15420             String names[] = cpr.info.authority.split(";");
15421             for (int j = 0; j < names.length; j++) {
15422                 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
15423             }
15424         }
15425
15426         for (int i = cpr.connections.size() - 1; i >= 0; i--) {
15427             ContentProviderConnection conn = cpr.connections.get(i);
15428             if (conn.waiting) {
15429                 // If this connection is waiting for the provider, then we don't
15430                 // need to mess with its process unless we are always removing
15431                 // or for some reason the provider is not currently launching.
15432                 if (inLaunching && !always) {
15433                     continue;
15434                 }
15435             }
15436             ProcessRecord capp = conn.client;
15437             conn.dead = true;
15438             if (conn.stableCount > 0) {
15439                 if (!capp.persistent && capp.thread != null
15440                         && capp.pid != 0
15441                         && capp.pid != MY_PID) {
15442                     capp.kill("depends on provider "
15443                             + cpr.name.flattenToShortString()
15444                             + " in dying proc " + (proc != null ? proc.processName : "??"), true);
15445                 }
15446             } else if (capp.thread != null && conn.provider.provider != null) {
15447                 try {
15448                     capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
15449                 } catch (RemoteException e) {
15450                 }
15451                 // In the protocol here, we don't expect the client to correctly
15452                 // clean up this connection, we'll just remove it.
15453                 cpr.connections.remove(i);
15454                 if (conn.client.conProviders.remove(conn)) {
15455                     stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
15456                 }
15457             }
15458         }
15459
15460         if (inLaunching && always) {
15461             mLaunchingProviders.remove(cpr);
15462         }
15463         return inLaunching;
15464     }
15465
15466     /**
15467      * Main code for cleaning up a process when it has gone away.  This is
15468      * called both as a result of the process dying, or directly when stopping
15469      * a process when running in single process mode.
15470      *
15471      * @return Returns true if the given process has been restarted, so the
15472      * app that was passed in must remain on the process lists.
15473      */
15474     private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
15475             boolean restarting, boolean allowRestart, int index) {
15476         if (index >= 0) {
15477             removeLruProcessLocked(app);
15478             ProcessList.remove(app.pid);
15479         }
15480
15481         mProcessesToGc.remove(app);
15482         mPendingPssProcesses.remove(app);
15483
15484         // Dismiss any open dialogs.
15485         if (app.crashDialog != null && !app.forceCrashReport) {
15486             app.crashDialog.dismiss();
15487             app.crashDialog = null;
15488         }
15489         if (app.anrDialog != null) {
15490             app.anrDialog.dismiss();
15491             app.anrDialog = null;
15492         }
15493         if (app.waitDialog != null) {
15494             app.waitDialog.dismiss();
15495             app.waitDialog = null;
15496         }
15497
15498         app.crashing = false;
15499         app.notResponding = false;
15500
15501         app.resetPackageList(mProcessStats);
15502         app.unlinkDeathRecipient();
15503         app.makeInactive(mProcessStats);
15504         app.waitingToKill = null;
15505         app.forcingToForeground = null;
15506         updateProcessForegroundLocked(app, false, false);
15507         app.foregroundActivities = false;
15508         app.hasShownUi = false;
15509         app.treatLikeActivity = false;
15510         app.hasAboveClient = false;
15511         app.hasClientActivities = false;
15512
15513         mServices.killServicesLocked(app, allowRestart);
15514
15515         boolean restart = false;
15516
15517         // Remove published content providers.
15518         for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
15519             ContentProviderRecord cpr = app.pubProviders.valueAt(i);
15520             final boolean always = app.bad || !allowRestart;
15521             boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
15522             if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
15523                 // We left the provider in the launching list, need to
15524                 // restart it.
15525                 restart = true;
15526             }
15527
15528             cpr.provider = null;
15529             cpr.proc = null;
15530         }
15531         app.pubProviders.clear();
15532
15533         // Take care of any launching providers waiting for this process.
15534         if (checkAppInLaunchingProvidersLocked(app, false)) {
15535             restart = true;
15536         }
15537
15538         // Unregister from connected content providers.
15539         if (!app.conProviders.isEmpty()) {
15540             for (int i = app.conProviders.size() - 1; i >= 0; i--) {
15541                 ContentProviderConnection conn = app.conProviders.get(i);
15542                 conn.provider.connections.remove(conn);
15543                 stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
15544                         conn.provider.name);
15545             }
15546             app.conProviders.clear();
15547         }
15548
15549         // At this point there may be remaining entries in mLaunchingProviders
15550         // where we were the only one waiting, so they are no longer of use.
15551         // Look for these and clean up if found.
15552         // XXX Commented out for now.  Trying to figure out a way to reproduce
15553         // the actual situation to identify what is actually going on.
15554         if (false) {
15555             for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
15556                 ContentProviderRecord cpr = mLaunchingProviders.get(i);
15557                 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
15558                     synchronized (cpr) {
15559                         cpr.launchingApp = null;
15560                         cpr.notifyAll();
15561                     }
15562                 }
15563             }
15564         }
15565
15566         skipCurrentReceiverLocked(app);
15567
15568         // Unregister any receivers.
15569         for (int i = app.receivers.size() - 1; i >= 0; i--) {
15570             removeReceiverLocked(app.receivers.valueAt(i));
15571         }
15572         app.receivers.clear();
15573
15574         // If the app is undergoing backup, tell the backup manager about it
15575         if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
15576             if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
15577                     + mBackupTarget.appInfo + " died during backup");
15578             try {
15579                 IBackupManager bm = IBackupManager.Stub.asInterface(
15580                         ServiceManager.getService(Context.BACKUP_SERVICE));
15581                 bm.agentDisconnected(app.info.packageName);
15582             } catch (RemoteException e) {
15583                 // can't happen; backup manager is local
15584             }
15585         }
15586
15587         for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
15588             ProcessChangeItem item = mPendingProcessChanges.get(i);
15589             if (item.pid == app.pid) {
15590                 mPendingProcessChanges.remove(i);
15591                 mAvailProcessChanges.add(item);
15592             }
15593         }
15594         mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
15595
15596         // If the caller is restarting this app, then leave it in its
15597         // current lists and let the caller take care of it.
15598         if (restarting) {
15599             return false;
15600         }
15601
15602         if (!app.persistent || app.isolated) {
15603             if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
15604                     "Removing non-persistent process during cleanup: " + app);
15605             removeProcessNameLocked(app.processName, app.uid);
15606             if (mHeavyWeightProcess == app) {
15607                 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
15608                         mHeavyWeightProcess.userId, 0));
15609                 mHeavyWeightProcess = null;
15610             }
15611         } else if (!app.removed) {
15612             // This app is persistent, so we need to keep its record around.
15613             // If it is not already on the pending app list, add it there
15614             // and start a new process for it.
15615             if (mPersistentStartingProcesses.indexOf(app) < 0) {
15616                 mPersistentStartingProcesses.add(app);
15617                 restart = true;
15618             }
15619         }
15620         if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
15621                 TAG_CLEANUP, "Clean-up removing on hold: " + app);
15622         mProcessesOnHold.remove(app);
15623
15624         if (app == mHomeProcess) {
15625             mHomeProcess = null;
15626         }
15627         if (app == mPreviousProcess) {
15628             mPreviousProcess = null;
15629         }
15630
15631         if (restart && !app.isolated) {
15632             // We have components that still need to be running in the
15633             // process, so re-launch it.
15634             if (index < 0) {
15635                 ProcessList.remove(app.pid);
15636             }
15637             addProcessNameLocked(app);
15638             startProcessLocked(app, "restart", app.processName);
15639             return true;
15640         } else if (app.pid > 0 && app.pid != MY_PID) {
15641             // Goodbye!
15642             boolean removed;
15643             synchronized (mPidsSelfLocked) {
15644                 mPidsSelfLocked.remove(app.pid);
15645                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
15646             }
15647             mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
15648             if (app.isolated) {
15649                 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
15650             }
15651             app.setPid(0);
15652         }
15653         return false;
15654     }
15655
15656     boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
15657         // Look through the content providers we are waiting to have launched,
15658         // and if any run in this process then either schedule a restart of
15659         // the process or kill the client waiting for it if this process has
15660         // gone bad.
15661         boolean restart = false;
15662         for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
15663             ContentProviderRecord cpr = mLaunchingProviders.get(i);
15664             if (cpr.launchingApp == app) {
15665                 if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
15666                     restart = true;
15667                 } else {
15668                     removeDyingProviderLocked(app, cpr, true);
15669                 }
15670             }
15671         }
15672         return restart;
15673     }
15674
15675     // =========================================================
15676     // SERVICES
15677     // =========================================================
15678
15679     @Override
15680     public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
15681             int flags) {
15682         enforceNotIsolatedCaller("getServices");
15683         synchronized (this) {
15684             return mServices.getRunningServiceInfoLocked(maxNum, flags);
15685         }
15686     }
15687
15688     @Override
15689     public PendingIntent getRunningServiceControlPanel(ComponentName name) {
15690         enforceNotIsolatedCaller("getRunningServiceControlPanel");
15691         synchronized (this) {
15692             return mServices.getRunningServiceControlPanelLocked(name);
15693         }
15694     }
15695
15696     @Override
15697     public ComponentName startService(IApplicationThread caller, Intent service,
15698             String resolvedType, String callingPackage, int userId)
15699             throws TransactionTooLargeException {
15700         enforceNotIsolatedCaller("startService");
15701         // Refuse possible leaked file descriptors
15702         if (service != null && service.hasFileDescriptors() == true) {
15703             throw new IllegalArgumentException("File descriptors passed in Intent");
15704         }
15705
15706         if (callingPackage == null) {
15707             throw new IllegalArgumentException("callingPackage cannot be null");
15708         }
15709
15710         if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
15711                 "startService: " + service + " type=" + resolvedType);
15712         synchronized(this) {
15713             final int callingPid = Binder.getCallingPid();
15714             final int callingUid = Binder.getCallingUid();
15715             final long origId = Binder.clearCallingIdentity();
15716             ComponentName res = mServices.startServiceLocked(caller, service,
15717                     resolvedType, callingPid, callingUid, callingPackage, userId);
15718             Binder.restoreCallingIdentity(origId);
15719             return res;
15720         }
15721     }
15722
15723     ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
15724             String callingPackage, int userId)
15725             throws TransactionTooLargeException {
15726         synchronized(this) {
15727             if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
15728                     "startServiceInPackage: " + service + " type=" + resolvedType);
15729             final long origId = Binder.clearCallingIdentity();
15730             ComponentName res = mServices.startServiceLocked(null, service,
15731                     resolvedType, -1, uid, callingPackage, userId);
15732             Binder.restoreCallingIdentity(origId);
15733             return res;
15734         }
15735     }
15736
15737     @Override
15738     public int stopService(IApplicationThread caller, Intent service,
15739             String resolvedType, int userId) {
15740         enforceNotIsolatedCaller("stopService");
15741         // Refuse possible leaked file descriptors
15742         if (service != null && service.hasFileDescriptors() == true) {
15743             throw new IllegalArgumentException("File descriptors passed in Intent");
15744         }
15745
15746         synchronized(this) {
15747             return mServices.stopServiceLocked(caller, service, resolvedType, userId);
15748         }
15749     }
15750
15751     @Override
15752     public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
15753         enforceNotIsolatedCaller("peekService");
15754         // Refuse possible leaked file descriptors
15755         if (service != null && service.hasFileDescriptors() == true) {
15756             throw new IllegalArgumentException("File descriptors passed in Intent");
15757         }
15758
15759         if (callingPackage == null) {
15760             throw new IllegalArgumentException("callingPackage cannot be null");
15761         }
15762
15763         synchronized(this) {
15764             return mServices.peekServiceLocked(service, resolvedType, callingPackage);
15765         }
15766     }
15767
15768     @Override
15769     public boolean stopServiceToken(ComponentName className, IBinder token,
15770             int startId) {
15771         synchronized(this) {
15772             return mServices.stopServiceTokenLocked(className, token, startId);
15773         }
15774     }
15775
15776     @Override
15777     public void setServiceForeground(ComponentName className, IBinder token,
15778             int id, Notification notification, boolean removeNotification) {
15779         synchronized(this) {
15780             mServices.setServiceForegroundLocked(className, token, id, notification,
15781                     removeNotification);
15782         }
15783     }
15784
15785     @Override
15786     public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
15787             boolean requireFull, String name, String callerPackage) {
15788         return handleIncomingUser(callingPid, callingUid, userId, allowAll,
15789                 requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
15790     }
15791
15792     int unsafeConvertIncomingUser(int userId) {
15793         return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
15794                 ? mCurrentUserId : userId;
15795     }
15796
15797     int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
15798             int allowMode, String name, String callerPackage) {
15799         final int callingUserId = UserHandle.getUserId(callingUid);
15800         if (callingUserId == userId) {
15801             return userId;
15802         }
15803
15804         // Note that we may be accessing mCurrentUserId outside of a lock...
15805         // shouldn't be a big deal, if this is being called outside
15806         // of a locked context there is intrinsically a race with
15807         // the value the caller will receive and someone else changing it.
15808         // We assume that USER_CURRENT_OR_SELF will use the current user; later
15809         // we will switch to the calling user if access to the current user fails.
15810         int targetUserId = unsafeConvertIncomingUser(userId);
15811
15812         if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
15813             final boolean allow;
15814             if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
15815                     callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
15816                 // If the caller has this permission, they always pass go.  And collect $200.
15817                 allow = true;
15818             } else if (allowMode == ALLOW_FULL_ONLY) {
15819                 // We require full access, sucks to be you.
15820                 allow = false;
15821             } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
15822                     callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
15823                 // If the caller does not have either permission, they are always doomed.
15824                 allow = false;
15825             } else if (allowMode == ALLOW_NON_FULL) {
15826                 // We are blanket allowing non-full access, you lucky caller!
15827                 allow = true;
15828             } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
15829                 // We may or may not allow this depending on whether the two users are
15830                 // in the same profile.
15831                 synchronized (mUserProfileGroupIdsSelfLocked) {
15832                     int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
15833                             UserInfo.NO_PROFILE_GROUP_ID);
15834                     int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
15835                             UserInfo.NO_PROFILE_GROUP_ID);
15836                     allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
15837                             && callingProfile == targetProfile;
15838                 }
15839             } else {
15840                 throw new IllegalArgumentException("Unknown mode: " + allowMode);
15841             }
15842             if (!allow) {
15843                 if (userId == UserHandle.USER_CURRENT_OR_SELF) {
15844                     // In this case, they would like to just execute as their
15845                     // owner user instead of failing.
15846                     targetUserId = callingUserId;
15847                 } else {
15848                     StringBuilder builder = new StringBuilder(128);
15849                     builder.append("Permission Denial: ");
15850                     builder.append(name);
15851                     if (callerPackage != null) {
15852                         builder.append(" from ");
15853                         builder.append(callerPackage);
15854                     }
15855                     builder.append(" asks to run as user ");
15856                     builder.append(userId);
15857                     builder.append(" but is calling from user ");
15858                     builder.append(UserHandle.getUserId(callingUid));
15859                     builder.append("; this requires ");
15860                     builder.append(INTERACT_ACROSS_USERS_FULL);
15861                     if (allowMode != ALLOW_FULL_ONLY) {
15862                         builder.append(" or ");
15863                         builder.append(INTERACT_ACROSS_USERS);
15864                     }
15865                     String msg = builder.toString();
15866                     Slog.w(TAG, msg);
15867                     throw new SecurityException(msg);
15868                 }
15869             }
15870         }
15871         if (!allowAll && targetUserId < 0) {
15872             throw new IllegalArgumentException(
15873                     "Call does not support special user #" + targetUserId);
15874         }
15875         // Check shell permission
15876         if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) {
15877             if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES,
15878                     targetUserId)) {
15879                 throw new SecurityException("Shell does not have permission to access user "
15880                         + targetUserId + "\n " + Debug.getCallers(3));
15881             }
15882         }
15883         return targetUserId;
15884     }
15885
15886     boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
15887             String className, int flags) {
15888         boolean result = false;
15889         // For apps that don't have pre-defined UIDs, check for permission
15890         if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
15891             if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
15892                 if (ActivityManager.checkUidPermission(
15893                         INTERACT_ACROSS_USERS,
15894                         aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
15895                     ComponentName comp = new ComponentName(aInfo.packageName, className);
15896                     String msg = "Permission Denial: Component " + comp.flattenToShortString()
15897                             + " requests FLAG_SINGLE_USER, but app does not hold "
15898                             + INTERACT_ACROSS_USERS;
15899                     Slog.w(TAG, msg);
15900                     throw new SecurityException(msg);
15901                 }
15902                 // Permission passed
15903                 result = true;
15904             }
15905         } else if ("system".equals(componentProcessName)) {
15906             result = true;
15907         } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
15908             // Phone app and persistent apps are allowed to export singleuser providers.
15909             result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
15910                     || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
15911         }
15912         if (DEBUG_MU) Slog.v(TAG_MU,
15913                 "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
15914                 + Integer.toHexString(flags) + ") = " + result);
15915         return result;
15916     }
15917
15918     /**
15919      * Checks to see if the caller is in the same app as the singleton
15920      * component, or the component is in a special app. It allows special apps
15921      * to export singleton components but prevents exporting singleton
15922      * components for regular apps.
15923      */
15924     boolean isValidSingletonCall(int callingUid, int componentUid) {
15925         int componentAppId = UserHandle.getAppId(componentUid);
15926         return UserHandle.isSameApp(callingUid, componentUid)
15927                 || componentAppId == Process.SYSTEM_UID
15928                 || componentAppId == Process.PHONE_UID
15929                 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
15930                         == PackageManager.PERMISSION_GRANTED;
15931     }
15932
15933     public int bindService(IApplicationThread caller, IBinder token, Intent service,
15934             String resolvedType, IServiceConnection connection, int flags, String callingPackage,
15935             int userId) throws TransactionTooLargeException {
15936         enforceNotIsolatedCaller("bindService");
15937
15938         // Refuse possible leaked file descriptors
15939         if (service != null && service.hasFileDescriptors() == true) {
15940             throw new IllegalArgumentException("File descriptors passed in Intent");
15941         }
15942
15943         if (callingPackage == null) {
15944             throw new IllegalArgumentException("callingPackage cannot be null");
15945         }
15946
15947         synchronized(this) {
15948             return mServices.bindServiceLocked(caller, token, service,
15949                     resolvedType, connection, flags, callingPackage, userId);
15950         }
15951     }
15952
15953     public boolean unbindService(IServiceConnection connection) {
15954         synchronized (this) {
15955             return mServices.unbindServiceLocked(connection);
15956         }
15957     }
15958
15959     public void publishService(IBinder token, Intent intent, IBinder service) {
15960         // Refuse possible leaked file descriptors
15961         if (intent != null && intent.hasFileDescriptors() == true) {
15962             throw new IllegalArgumentException("File descriptors passed in Intent");
15963         }
15964
15965         synchronized(this) {
15966             if (!(token instanceof ServiceRecord)) {
15967                 throw new IllegalArgumentException("Invalid service token");
15968             }
15969             mServices.publishServiceLocked((ServiceRecord)token, intent, service);
15970         }
15971     }
15972
15973     public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
15974         // Refuse possible leaked file descriptors
15975         if (intent != null && intent.hasFileDescriptors() == true) {
15976             throw new IllegalArgumentException("File descriptors passed in Intent");
15977         }
15978
15979         synchronized(this) {
15980             mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
15981         }
15982     }
15983
15984     public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
15985         synchronized(this) {
15986             if (!(token instanceof ServiceRecord)) {
15987                 Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
15988                 throw new IllegalArgumentException("Invalid service token");
15989             }
15990             mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
15991         }
15992     }
15993
15994     // =========================================================
15995     // BACKUP AND RESTORE
15996     // =========================================================
15997
15998     // Cause the target app to be launched if necessary and its backup agent
15999     // instantiated.  The backup agent will invoke backupAgentCreated() on the
16000     // activity manager to announce its creation.
16001     public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
16002         if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
16003                 "bindBackupAgent: app=" + app + " mode=" + backupMode);
16004         enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
16005
16006         synchronized(this) {
16007             // !!! TODO: currently no check here that we're already bound
16008             BatteryStatsImpl.Uid.Pkg.Serv ss = null;
16009             BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16010             synchronized (stats) {
16011                 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
16012             }
16013
16014             // Backup agent is now in use, its package can't be stopped.
16015             try {
16016                 AppGlobals.getPackageManager().setPackageStoppedState(
16017                         app.packageName, false, UserHandle.getUserId(app.uid));
16018             } catch (RemoteException e) {
16019             } catch (IllegalArgumentException e) {
16020                 Slog.w(TAG, "Failed trying to unstop package "
16021                         + app.packageName + ": " + e);
16022             }
16023
16024             BackupRecord r = new BackupRecord(ss, app, backupMode);
16025             ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
16026                     ? new ComponentName(app.packageName, app.backupAgentName)
16027                     : new ComponentName("android", "FullBackupAgent");
16028             // startProcessLocked() returns existing proc's record if it's already running
16029             ProcessRecord proc = startProcessLocked(app.processName, app,
16030                     false, 0, "backup", hostingName, false, false, false);
16031             if (proc == null) {
16032                 Slog.e(TAG, "Unable to start backup agent process " + r);
16033                 return false;
16034             }
16035
16036             r.app = proc;
16037             mBackupTarget = r;
16038             mBackupAppName = app.packageName;
16039
16040             // Try not to kill the process during backup
16041             updateOomAdjLocked(proc);
16042
16043             // If the process is already attached, schedule the creation of the backup agent now.
16044             // If it is not yet live, this will be done when it attaches to the framework.
16045             if (proc.thread != null) {
16046                 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
16047                 try {
16048                     proc.thread.scheduleCreateBackupAgent(app,
16049                             compatibilityInfoForPackageLocked(app), backupMode);
16050                 } catch (RemoteException e) {
16051                     // Will time out on the backup manager side
16052                 }
16053             } else {
16054                 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
16055             }
16056             // Invariants: at this point, the target app process exists and the application
16057             // is either already running or in the process of coming up.  mBackupTarget and
16058             // mBackupAppName describe the app, so that when it binds back to the AM we
16059             // know that it's scheduled for a backup-agent operation.
16060         }
16061
16062         return true;
16063     }
16064
16065     @Override
16066     public void clearPendingBackup() {
16067         if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
16068         enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
16069
16070         synchronized (this) {
16071             mBackupTarget = null;
16072             mBackupAppName = null;
16073         }
16074     }
16075
16076     // A backup agent has just come up
16077     public void backupAgentCreated(String agentPackageName, IBinder agent) {
16078         if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
16079                 + " = " + agent);
16080
16081         synchronized(this) {
16082             if (!agentPackageName.equals(mBackupAppName)) {
16083                 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
16084                 return;
16085             }
16086         }
16087
16088         long oldIdent = Binder.clearCallingIdentity();
16089         try {
16090             IBackupManager bm = IBackupManager.Stub.asInterface(
16091                     ServiceManager.getService(Context.BACKUP_SERVICE));
16092             bm.agentConnected(agentPackageName, agent);
16093         } catch (RemoteException e) {
16094             // can't happen; the backup manager service is local
16095         } catch (Exception e) {
16096             Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
16097             e.printStackTrace();
16098         } finally {
16099             Binder.restoreCallingIdentity(oldIdent);
16100         }
16101     }
16102
16103     // done with this agent
16104     public void unbindBackupAgent(ApplicationInfo appInfo) {
16105         if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
16106         if (appInfo == null) {
16107             Slog.w(TAG, "unbind backup agent for null app");
16108             return;
16109         }
16110
16111         synchronized(this) {
16112             try {
16113                 if (mBackupAppName == null) {
16114                     Slog.w(TAG, "Unbinding backup agent with no active backup");
16115                     return;
16116                 }
16117
16118                 if (!mBackupAppName.equals(appInfo.packageName)) {
16119                     Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
16120                     return;
16121                 }
16122
16123                 // Not backing this app up any more; reset its OOM adjustment
16124                 final ProcessRecord proc = mBackupTarget.app;
16125                 updateOomAdjLocked(proc);
16126
16127                 // If the app crashed during backup, 'thread' will be null here
16128                 if (proc.thread != null) {
16129                     try {
16130                         proc.thread.scheduleDestroyBackupAgent(appInfo,
16131                                 compatibilityInfoForPackageLocked(appInfo));
16132                     } catch (Exception e) {
16133                         Slog.e(TAG, "Exception when unbinding backup agent:");
16134                         e.printStackTrace();
16135                     }
16136                 }
16137             } finally {
16138                 mBackupTarget = null;
16139                 mBackupAppName = null;
16140             }
16141         }
16142     }
16143     // =========================================================
16144     // BROADCASTS
16145     // =========================================================
16146
16147     boolean isPendingBroadcastProcessLocked(int pid) {
16148         return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
16149                 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
16150     }
16151
16152     void skipPendingBroadcastLocked(int pid) {
16153             Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
16154             for (BroadcastQueue queue : mBroadcastQueues) {
16155                 queue.skipPendingBroadcastLocked(pid);
16156             }
16157     }
16158
16159     // The app just attached; send any pending broadcasts that it should receive
16160     boolean sendPendingBroadcastsLocked(ProcessRecord app) {
16161         boolean didSomething = false;
16162         for (BroadcastQueue queue : mBroadcastQueues) {
16163             didSomething |= queue.sendPendingBroadcastsLocked(app);
16164         }
16165         return didSomething;
16166     }
16167
16168     public Intent registerReceiver(IApplicationThread caller, String callerPackage,
16169             IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
16170         enforceNotIsolatedCaller("registerReceiver");
16171         ArrayList<Intent> stickyIntents = null;
16172         ProcessRecord callerApp = null;
16173         int callingUid;
16174         int callingPid;
16175         synchronized(this) {
16176             if (caller != null) {
16177                 callerApp = getRecordForAppLocked(caller);
16178                 if (callerApp == null) {
16179                     throw new SecurityException(
16180                             "Unable to find app for caller " + caller
16181                             + " (pid=" + Binder.getCallingPid()
16182                             + ") when registering receiver " + receiver);
16183                 }
16184                 if (callerApp.info.uid != Process.SYSTEM_UID &&
16185                         !callerApp.pkgList.containsKey(callerPackage) &&
16186                         !"android".equals(callerPackage)) {
16187                     throw new SecurityException("Given caller package " + callerPackage
16188                             + " is not running in process " + callerApp);
16189                 }
16190                 callingUid = callerApp.info.uid;
16191                 callingPid = callerApp.pid;
16192             } else {
16193                 callerPackage = null;
16194                 callingUid = Binder.getCallingUid();
16195                 callingPid = Binder.getCallingPid();
16196             }
16197
16198             userId = handleIncomingUser(callingPid, callingUid, userId,
16199                     true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
16200
16201             Iterator<String> actions = filter.actionsIterator();
16202             if (actions == null) {
16203                 ArrayList<String> noAction = new ArrayList<String>(1);
16204                 noAction.add(null);
16205                 actions = noAction.iterator();
16206             }
16207
16208             // Collect stickies of users
16209             int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
16210             while (actions.hasNext()) {
16211                 String action = actions.next();
16212                 for (int id : userIds) {
16213                     ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
16214                     if (stickies != null) {
16215                         ArrayList<Intent> intents = stickies.get(action);
16216                         if (intents != null) {
16217                             if (stickyIntents == null) {
16218                                 stickyIntents = new ArrayList<Intent>();
16219                             }
16220                             stickyIntents.addAll(intents);
16221                         }
16222                     }
16223                 }
16224             }
16225         }
16226
16227         ArrayList<Intent> allSticky = null;
16228         if (stickyIntents != null) {
16229             final ContentResolver resolver = mContext.getContentResolver();
16230             // Look for any matching sticky broadcasts...
16231             for (int i = 0, N = stickyIntents.size(); i < N; i++) {
16232                 Intent intent = stickyIntents.get(i);
16233                 // If intent has scheme "content", it will need to acccess
16234                 // provider that needs to lock mProviderMap in ActivityThread
16235                 // and also it may need to wait application response, so we
16236                 // cannot lock ActivityManagerService here.
16237                 if (filter.match(resolver, intent, true, TAG) >= 0) {
16238                     if (allSticky == null) {
16239                         allSticky = new ArrayList<Intent>();
16240                     }
16241                     allSticky.add(intent);
16242                 }
16243             }
16244         }
16245
16246         // The first sticky in the list is returned directly back to the client.
16247         Intent sticky = allSticky != null ? allSticky.get(0) : null;
16248         if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
16249         if (receiver == null) {
16250             return sticky;
16251         }
16252
16253         synchronized (this) {
16254             if (callerApp != null && (callerApp.thread == null
16255                     || callerApp.thread.asBinder() != caller.asBinder())) {
16256                 // Original caller already died
16257                 return null;
16258             }
16259             ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
16260             if (rl == null) {
16261                 rl = new ReceiverList(this, callerApp, callingPid, callingUid,
16262                         userId, receiver);
16263                 if (rl.app != null) {
16264                     rl.app.receivers.add(rl);
16265                 } else {
16266                     try {
16267                         receiver.asBinder().linkToDeath(rl, 0);
16268                     } catch (RemoteException e) {
16269                         return sticky;
16270                     }
16271                     rl.linkedToDeath = true;
16272                 }
16273                 mRegisteredReceivers.put(receiver.asBinder(), rl);
16274             } else if (rl.uid != callingUid) {
16275                 throw new IllegalArgumentException(
16276                         "Receiver requested to register for uid " + callingUid
16277                         + " was previously registered for uid " + rl.uid);
16278             } else if (rl.pid != callingPid) {
16279                 throw new IllegalArgumentException(
16280                         "Receiver requested to register for pid " + callingPid
16281                         + " was previously registered for pid " + rl.pid);
16282             } else if (rl.userId != userId) {
16283                 throw new IllegalArgumentException(
16284                         "Receiver requested to register for user " + userId
16285                         + " was previously registered for user " + rl.userId);
16286             }
16287             BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
16288                     permission, callingUid, userId);
16289             rl.add(bf);
16290             if (!bf.debugCheck()) {
16291                 Slog.w(TAG, "==> For Dynamic broadcast");
16292             }
16293             mReceiverResolver.addFilter(bf);
16294
16295             // Enqueue broadcasts for all existing stickies that match
16296             // this filter.
16297             if (allSticky != null) {
16298                 ArrayList receivers = new ArrayList();
16299                 receivers.add(bf);
16300
16301                 final int stickyCount = allSticky.size();
16302                 for (int i = 0; i < stickyCount; i++) {
16303                     Intent intent = allSticky.get(i);
16304                     BroadcastQueue queue = broadcastQueueForIntent(intent);
16305                     BroadcastRecord r = new BroadcastRecord(queue, intent, null,
16306                             null, -1, -1, null, null, AppOpsManager.OP_NONE, null, receivers,
16307                             null, 0, null, null, false, true, true, -1);
16308                     queue.enqueueParallelBroadcastLocked(r);
16309                     queue.scheduleBroadcastsLocked();
16310                 }
16311             }
16312
16313             return sticky;
16314         }
16315     }
16316
16317     public void unregisterReceiver(IIntentReceiver receiver) {
16318         if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
16319
16320         final long origId = Binder.clearCallingIdentity();
16321         try {
16322             boolean doTrim = false;
16323
16324             synchronized(this) {
16325                 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
16326                 if (rl != null) {
16327                     final BroadcastRecord r = rl.curBroadcast;
16328                     if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
16329                         final boolean doNext = r.queue.finishReceiverLocked(
16330                                 r, r.resultCode, r.resultData, r.resultExtras,
16331                                 r.resultAbort, false);
16332                         if (doNext) {
16333                             doTrim = true;
16334                             r.queue.processNextBroadcast(false);
16335                         }
16336                     }
16337
16338                     if (rl.app != null) {
16339                         rl.app.receivers.remove(rl);
16340                     }
16341                     removeReceiverLocked(rl);
16342                     if (rl.linkedToDeath) {
16343                         rl.linkedToDeath = false;
16344                         rl.receiver.asBinder().unlinkToDeath(rl, 0);
16345                     }
16346                 }
16347             }
16348
16349             // If we actually concluded any broadcasts, we might now be able
16350             // to trim the recipients' apps from our working set
16351             if (doTrim) {
16352                 trimApplications();
16353                 return;
16354             }
16355
16356         } finally {
16357             Binder.restoreCallingIdentity(origId);
16358         }
16359     }
16360
16361     void removeReceiverLocked(ReceiverList rl) {
16362         mRegisteredReceivers.remove(rl.receiver.asBinder());
16363         for (int i = rl.size() - 1; i >= 0; i--) {
16364             mReceiverResolver.removeFilter(rl.get(i));
16365         }
16366     }
16367
16368     private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
16369         for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
16370             ProcessRecord r = mLruProcesses.get(i);
16371             if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
16372                 try {
16373                     r.thread.dispatchPackageBroadcast(cmd, packages);
16374                 } catch (RemoteException ex) {
16375                 }
16376             }
16377         }
16378     }
16379
16380     private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
16381             int callingUid, int[] users) {
16382         List<ResolveInfo> receivers = null;
16383         try {
16384             HashSet<ComponentName> singleUserReceivers = null;
16385             boolean scannedFirstReceivers = false;
16386             for (int user : users) {
16387                 // Skip users that have Shell restrictions
16388                 if (callingUid == Process.SHELL_UID
16389                         && getUserManagerLocked().hasUserRestriction(
16390                                 UserManager.DISALLOW_DEBUGGING_FEATURES, user)) {
16391                     continue;
16392                 }
16393                 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
16394                         .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
16395                 if (user != UserHandle.USER_OWNER && newReceivers != null) {
16396                     // If this is not the primary user, we need to check for
16397                     // any receivers that should be filtered out.
16398                     for (int i=0; i<newReceivers.size(); i++) {
16399                         ResolveInfo ri = newReceivers.get(i);
16400                         if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
16401                             newReceivers.remove(i);
16402                             i--;
16403                         }
16404                     }
16405                 }
16406                 if (newReceivers != null && newReceivers.size() == 0) {
16407                     newReceivers = null;
16408                 }
16409                 if (receivers == null) {
16410                     receivers = newReceivers;
16411                 } else if (newReceivers != null) {
16412                     // We need to concatenate the additional receivers
16413                     // found with what we have do far.  This would be easy,
16414                     // but we also need to de-dup any receivers that are
16415                     // singleUser.
16416                     if (!scannedFirstReceivers) {
16417                         // Collect any single user receivers we had already retrieved.
16418                         scannedFirstReceivers = true;
16419                         for (int i=0; i<receivers.size(); i++) {
16420                             ResolveInfo ri = receivers.get(i);
16421                             if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
16422                                 ComponentName cn = new ComponentName(
16423                                         ri.activityInfo.packageName, ri.activityInfo.name);
16424                                 if (singleUserReceivers == null) {
16425                                     singleUserReceivers = new HashSet<ComponentName>();
16426                                 }
16427                                 singleUserReceivers.add(cn);
16428                             }
16429                         }
16430                     }
16431                     // Add the new results to the existing results, tracking
16432                     // and de-dupping single user receivers.
16433                     for (int i=0; i<newReceivers.size(); i++) {
16434                         ResolveInfo ri = newReceivers.get(i);
16435                         if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
16436                             ComponentName cn = new ComponentName(
16437                                     ri.activityInfo.packageName, ri.activityInfo.name);
16438                             if (singleUserReceivers == null) {
16439                                 singleUserReceivers = new HashSet<ComponentName>();
16440                             }
16441                             if (!singleUserReceivers.contains(cn)) {
16442                                 singleUserReceivers.add(cn);
16443                                 receivers.add(ri);
16444                             }
16445                         } else {
16446                             receivers.add(ri);
16447                         }
16448                     }
16449                 }
16450             }
16451         } catch (RemoteException ex) {
16452             // pm is in same process, this will never happen.
16453         }
16454         return receivers;
16455     }
16456
16457     private final int broadcastIntentLocked(ProcessRecord callerApp,
16458             String callerPackage, Intent intent, String resolvedType,
16459             IIntentReceiver resultTo, int resultCode, String resultData,
16460             Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle options,
16461             boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
16462         intent = new Intent(intent);
16463
16464         // By default broadcasts do not go to stopped apps.
16465         intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
16466
16467         // If we have not finished booting, don't allow this to launch new processes.
16468         if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
16469             intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16470         }
16471
16472         if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
16473                 (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
16474                 + " ordered=" + ordered + " userid=" + userId);
16475         if ((resultTo != null) && !ordered) {
16476             Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
16477         }
16478
16479         userId = handleIncomingUser(callingPid, callingUid, userId,
16480                 true, ALLOW_NON_FULL, "broadcast", callerPackage);
16481
16482         // Make sure that the user who is receiving this broadcast is running.
16483         // If not, we will just skip it. Make an exception for shutdown broadcasts
16484         // and upgrade steps.
16485
16486         if (userId != UserHandle.USER_ALL && !isUserRunningLocked(userId, false)) {
16487             if ((callingUid != Process.SYSTEM_UID
16488                     || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
16489                     && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
16490                 Slog.w(TAG, "Skipping broadcast of " + intent
16491                         + ": user " + userId + " is stopped");
16492                 return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
16493             }
16494         }
16495
16496         BroadcastOptions brOptions = null;
16497         if (options != null) {
16498             brOptions = new BroadcastOptions(options);
16499             if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
16500                 // See if the caller is allowed to do this.  Note we are checking against
16501                 // the actual real caller (not whoever provided the operation as say a
16502                 // PendingIntent), because that who is actually supplied the arguments.
16503                 if (checkComponentPermission(
16504                         android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
16505                         Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
16506                         != PackageManager.PERMISSION_GRANTED) {
16507                     String msg = "Permission Denial: " + intent.getAction()
16508                             + " broadcast from " + callerPackage + " (pid=" + callingPid
16509                             + ", uid=" + callingUid + ")"
16510                             + " requires "
16511                             + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
16512                     Slog.w(TAG, msg);
16513                     throw new SecurityException(msg);
16514                 }
16515             }
16516         }
16517
16518         /*
16519          * Prevent non-system code (defined here to be non-persistent
16520          * processes) from sending protected broadcasts.
16521          */
16522         int callingAppId = UserHandle.getAppId(callingUid);
16523         if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
16524             || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
16525             || callingAppId == Process.NFC_UID || callingUid == 0) {
16526             // Always okay.
16527         } else if (callerApp == null || !callerApp.persistent) {
16528             try {
16529                 if (AppGlobals.getPackageManager().isProtectedBroadcast(
16530                         intent.getAction())) {
16531                     String msg = "Permission Denial: not allowed to send broadcast "
16532                             + intent.getAction() + " from pid="
16533                             + callingPid + ", uid=" + callingUid;
16534                     Slog.w(TAG, msg);
16535                     throw new SecurityException(msg);
16536                 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
16537                     // Special case for compatibility: we don't want apps to send this,
16538                     // but historically it has not been protected and apps may be using it
16539                     // to poke their own app widget.  So, instead of making it protected,
16540                     // just limit it to the caller.
16541                     if (callerApp == null) {
16542                         String msg = "Permission Denial: not allowed to send broadcast "
16543                                 + intent.getAction() + " from unknown caller.";
16544                         Slog.w(TAG, msg);
16545                         throw new SecurityException(msg);
16546                     } else if (intent.getComponent() != null) {
16547                         // They are good enough to send to an explicit component...  verify
16548                         // it is being sent to the calling app.
16549                         if (!intent.getComponent().getPackageName().equals(
16550                                 callerApp.info.packageName)) {
16551                             String msg = "Permission Denial: not allowed to send broadcast "
16552                                     + intent.getAction() + " to "
16553                                     + intent.getComponent().getPackageName() + " from "
16554                                     + callerApp.info.packageName;
16555                             Slog.w(TAG, msg);
16556                             throw new SecurityException(msg);
16557                         }
16558                     } else {
16559                         // Limit broadcast to their own package.
16560                         intent.setPackage(callerApp.info.packageName);
16561                     }
16562                 }
16563             } catch (RemoteException e) {
16564                 Slog.w(TAG, "Remote exception", e);
16565                 return ActivityManager.BROADCAST_SUCCESS;
16566             }
16567         }
16568
16569         final String action = intent.getAction();
16570         if (action != null) {
16571             switch (action) {
16572                 case Intent.ACTION_UID_REMOVED:
16573                 case Intent.ACTION_PACKAGE_REMOVED:
16574                 case Intent.ACTION_PACKAGE_CHANGED:
16575                 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
16576                 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
16577                     // Handle special intents: if this broadcast is from the package
16578                     // manager about a package being removed, we need to remove all of
16579                     // its activities from the history stack.
16580                     if (checkComponentPermission(
16581                             android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
16582                             callingPid, callingUid, -1, true)
16583                             != PackageManager.PERMISSION_GRANTED) {
16584                         String msg = "Permission Denial: " + intent.getAction()
16585                                 + " broadcast from " + callerPackage + " (pid=" + callingPid
16586                                 + ", uid=" + callingUid + ")"
16587                                 + " requires "
16588                                 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
16589                         Slog.w(TAG, msg);
16590                         throw new SecurityException(msg);
16591                     }
16592                     switch (action) {
16593                         case Intent.ACTION_UID_REMOVED:
16594                             final Bundle intentExtras = intent.getExtras();
16595                             final int uid = intentExtras != null
16596                                     ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
16597                             if (uid >= 0) {
16598                                 mBatteryStatsService.removeUid(uid);
16599                                 mAppOpsService.uidRemoved(uid);
16600                             }
16601                             break;
16602                         case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
16603                             // If resources are unavailable just force stop all those packages
16604                             // and flush the attribute cache as well.
16605                             String list[] =
16606                                     intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
16607                             if (list != null && list.length > 0) {
16608                                 for (int i = 0; i < list.length; i++) {
16609                                     forceStopPackageLocked(list[i], -1, false, true, true,
16610                                             false, false, userId, "storage unmount");
16611                                 }
16612                                 mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
16613                                 sendPackageBroadcastLocked(
16614                                         IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
16615                                         userId);
16616                             }
16617                             break;
16618                         case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
16619                             mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
16620                             break;
16621                         case Intent.ACTION_PACKAGE_REMOVED:
16622                         case Intent.ACTION_PACKAGE_CHANGED:
16623                             Uri data = intent.getData();
16624                             String ssp;
16625                             if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
16626                                 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
16627                                 boolean fullUninstall = removed &&
16628                                         !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
16629                                 final boolean killProcess =
16630                                         !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
16631                                 if (killProcess) {
16632                                     forceStopPackageLocked(ssp, UserHandle.getAppId(
16633                                             intent.getIntExtra(Intent.EXTRA_UID, -1)),
16634                                             false, true, true, false, fullUninstall, userId,
16635                                             removed ? "pkg removed" : "pkg changed");
16636                                 }
16637                                 if (removed) {
16638                                     sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
16639                                             new String[] {ssp}, userId);
16640                                     if (fullUninstall) {
16641                                         mAppOpsService.packageRemoved(
16642                                                 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
16643
16644                                         // Remove all permissions granted from/to this package
16645                                         removeUriPermissionsForPackageLocked(ssp, userId, true);
16646
16647                                         removeTasksByPackageNameLocked(ssp, userId);
16648                                         mBatteryStatsService.notePackageUninstalled(ssp);
16649                                     }
16650                                 } else {
16651                                     cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
16652                                             intent.getStringArrayExtra(
16653                                                     Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
16654                                 }
16655                             }
16656                             break;
16657                     }
16658                     break;
16659                 case Intent.ACTION_PACKAGE_ADDED:
16660                     // Special case for adding a package: by default turn on compatibility mode.
16661                     Uri data = intent.getData();
16662                     String ssp;
16663                     if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
16664                         final boolean replacing =
16665                                 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
16666                         mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
16667
16668                         try {
16669                             ApplicationInfo ai = AppGlobals.getPackageManager().
16670                                     getApplicationInfo(ssp, 0, 0);
16671                             mBatteryStatsService.notePackageInstalled(ssp,
16672                                     ai != null ? ai.versionCode : 0);
16673                         } catch (RemoteException e) {
16674                         }
16675                     }
16676                     break;
16677                 case Intent.ACTION_TIMEZONE_CHANGED:
16678                     // If this is the time zone changed action, queue up a message that will reset
16679                     // the timezone of all currently running processes. This message will get
16680                     // queued up before the broadcast happens.
16681                     mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
16682                     break;
16683                 case Intent.ACTION_TIME_CHANGED:
16684                     // If the user set the time, let all running processes know.
16685                     final int is24Hour =
16686                             intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
16687                                     : 0;
16688                     mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
16689                     BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16690                     synchronized (stats) {
16691                         stats.noteCurrentTimeChangedLocked();
16692                     }
16693                     break;
16694                 case Intent.ACTION_CLEAR_DNS_CACHE:
16695                     mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
16696                     break;
16697                 case Proxy.PROXY_CHANGE_ACTION:
16698                     ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
16699                     mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
16700                     break;
16701             }
16702         }
16703
16704         // Add to the sticky list if requested.
16705         if (sticky) {
16706             if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
16707                     callingPid, callingUid)
16708                     != PackageManager.PERMISSION_GRANTED) {
16709                 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
16710                         + callingPid + ", uid=" + callingUid
16711                         + " requires " + android.Manifest.permission.BROADCAST_STICKY;
16712                 Slog.w(TAG, msg);
16713                 throw new SecurityException(msg);
16714             }
16715             if (requiredPermissions != null && requiredPermissions.length > 0) {
16716                 Slog.w(TAG, "Can't broadcast sticky intent " + intent
16717                         + " and enforce permissions " + Arrays.toString(requiredPermissions));
16718                 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
16719             }
16720             if (intent.getComponent() != null) {
16721                 throw new SecurityException(
16722                         "Sticky broadcasts can't target a specific component");
16723             }
16724             // We use userId directly here, since the "all" target is maintained
16725             // as a separate set of sticky broadcasts.
16726             if (userId != UserHandle.USER_ALL) {
16727                 // But first, if this is not a broadcast to all users, then
16728                 // make sure it doesn't conflict with an existing broadcast to
16729                 // all users.
16730                 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
16731                         UserHandle.USER_ALL);
16732                 if (stickies != null) {
16733                     ArrayList<Intent> list = stickies.get(intent.getAction());
16734                     if (list != null) {
16735                         int N = list.size();
16736                         int i;
16737                         for (i=0; i<N; i++) {
16738                             if (intent.filterEquals(list.get(i))) {
16739                                 throw new IllegalArgumentException(
16740                                         "Sticky broadcast " + intent + " for user "
16741                                         + userId + " conflicts with existing global broadcast");
16742                             }
16743                         }
16744                     }
16745                 }
16746             }
16747             ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
16748             if (stickies == null) {
16749                 stickies = new ArrayMap<>();
16750                 mStickyBroadcasts.put(userId, stickies);
16751             }
16752             ArrayList<Intent> list = stickies.get(intent.getAction());
16753             if (list == null) {
16754                 list = new ArrayList<>();
16755                 stickies.put(intent.getAction(), list);
16756             }
16757             final int stickiesCount = list.size();
16758             int i;
16759             for (i = 0; i < stickiesCount; i++) {
16760                 if (intent.filterEquals(list.get(i))) {
16761                     // This sticky already exists, replace it.
16762                     list.set(i, new Intent(intent));
16763                     break;
16764                 }
16765             }
16766             if (i >= stickiesCount) {
16767                 list.add(new Intent(intent));
16768             }
16769         }
16770
16771         int[] users;
16772         if (userId == UserHandle.USER_ALL) {
16773             // Caller wants broadcast to go to all started users.
16774             users = mStartedUserArray;
16775         } else {
16776             // Caller wants broadcast to go to one specific user.
16777             users = new int[] {userId};
16778         }
16779
16780         // Figure out who all will receive this broadcast.
16781         List receivers = null;
16782         List<BroadcastFilter> registeredReceivers = null;
16783         // Need to resolve the intent to interested receivers...
16784         if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
16785                  == 0) {
16786             receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
16787         }
16788         if (intent.getComponent() == null) {
16789             if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
16790                 // Query one target user at a time, excluding shell-restricted users
16791                 UserManagerService ums = getUserManagerLocked();
16792                 for (int i = 0; i < users.length; i++) {
16793                     if (ums.hasUserRestriction(
16794                             UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
16795                         continue;
16796                     }
16797                     List<BroadcastFilter> registeredReceiversForUser =
16798                             mReceiverResolver.queryIntent(intent,
16799                                     resolvedType, false, users[i]);
16800                     if (registeredReceivers == null) {
16801                         registeredReceivers = registeredReceiversForUser;
16802                     } else if (registeredReceiversForUser != null) {
16803                         registeredReceivers.addAll(registeredReceiversForUser);
16804                     }
16805                 }
16806             } else {
16807                 registeredReceivers = mReceiverResolver.queryIntent(intent,
16808                         resolvedType, false, userId);
16809             }
16810         }
16811
16812         final boolean replacePending =
16813                 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
16814
16815         if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueing broadcast: " + intent.getAction()
16816                 + " replacePending=" + replacePending);
16817
16818         int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
16819         if (!ordered && NR > 0) {
16820             // If we are not serializing this broadcast, then send the
16821             // registered receivers separately so they don't wait for the
16822             // components to be launched.
16823             final BroadcastQueue queue = broadcastQueueForIntent(intent);
16824             BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
16825                     callerPackage, callingPid, callingUid, resolvedType, requiredPermissions,
16826                     appOp, brOptions, registeredReceivers, resultTo, resultCode, resultData,
16827                     resultExtras, ordered, sticky, false, userId);
16828             if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
16829             final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
16830             if (!replaced) {
16831                 queue.enqueueParallelBroadcastLocked(r);
16832                 queue.scheduleBroadcastsLocked();
16833             }
16834             registeredReceivers = null;
16835             NR = 0;
16836         }
16837
16838         // Merge into one list.
16839         int ir = 0;
16840         if (receivers != null) {
16841             // A special case for PACKAGE_ADDED: do not allow the package
16842             // being added to see this broadcast.  This prevents them from
16843             // using this as a back door to get run as soon as they are
16844             // installed.  Maybe in the future we want to have a special install
16845             // broadcast or such for apps, but we'd like to deliberately make
16846             // this decision.
16847             String skipPackages[] = null;
16848             if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
16849                     || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
16850                     || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
16851                 Uri data = intent.getData();
16852                 if (data != null) {
16853                     String pkgName = data.getSchemeSpecificPart();
16854                     if (pkgName != null) {
16855                         skipPackages = new String[] { pkgName };
16856                     }
16857                 }
16858             } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
16859                 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
16860             }
16861             if (skipPackages != null && (skipPackages.length > 0)) {
16862                 for (String skipPackage : skipPackages) {
16863                     if (skipPackage != null) {
16864                         int NT = receivers.size();
16865                         for (int it=0; it<NT; it++) {
16866                             ResolveInfo curt = (ResolveInfo)receivers.get(it);
16867                             if (curt.activityInfo.packageName.equals(skipPackage)) {
16868                                 receivers.remove(it);
16869                                 it--;
16870                                 NT--;
16871                             }
16872                         }
16873                     }
16874                 }
16875             }
16876
16877             int NT = receivers != null ? receivers.size() : 0;
16878             int it = 0;
16879             ResolveInfo curt = null;
16880             BroadcastFilter curr = null;
16881             while (it < NT && ir < NR) {
16882                 if (curt == null) {
16883                     curt = (ResolveInfo)receivers.get(it);
16884                 }
16885                 if (curr == null) {
16886                     curr = registeredReceivers.get(ir);
16887                 }
16888                 if (curr.getPriority() >= curt.priority) {
16889                     // Insert this broadcast record into the final list.
16890                     receivers.add(it, curr);
16891                     ir++;
16892                     curr = null;
16893                     it++;
16894                     NT++;
16895                 } else {
16896                     // Skip to the next ResolveInfo in the final list.
16897                     it++;
16898                     curt = null;
16899                 }
16900             }
16901         }
16902         while (ir < NR) {
16903             if (receivers == null) {
16904                 receivers = new ArrayList();
16905             }
16906             receivers.add(registeredReceivers.get(ir));
16907             ir++;
16908         }
16909
16910         if ((receivers != null && receivers.size() > 0)
16911                 || resultTo != null) {
16912             BroadcastQueue queue = broadcastQueueForIntent(intent);
16913             BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
16914                     callerPackage, callingPid, callingUid, resolvedType,
16915                     requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
16916                     resultData, resultExtras, ordered, sticky, false, userId);
16917
16918             if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
16919                     + ": prev had " + queue.mOrderedBroadcasts.size());
16920             if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
16921                     "Enqueueing broadcast " + r.intent.getAction());
16922
16923             boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
16924             if (!replaced) {
16925                 queue.enqueueOrderedBroadcastLocked(r);
16926                 queue.scheduleBroadcastsLocked();
16927             }
16928         }
16929
16930         return ActivityManager.BROADCAST_SUCCESS;
16931     }
16932
16933     final Intent verifyBroadcastLocked(Intent intent) {
16934         // Refuse possible leaked file descriptors
16935         if (intent != null && intent.hasFileDescriptors() == true) {
16936             throw new IllegalArgumentException("File descriptors passed in Intent");
16937         }
16938
16939         int flags = intent.getFlags();
16940
16941         if (!mProcessesReady) {
16942             // if the caller really truly claims to know what they're doing, go
16943             // ahead and allow the broadcast without launching any receivers
16944             if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
16945                 // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
16946             } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
16947                 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
16948                         + " before boot completion");
16949                 throw new IllegalStateException("Cannot broadcast before boot completed");
16950             }
16951         }
16952
16953         if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
16954             throw new IllegalArgumentException(
16955                     "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
16956         }
16957
16958         return intent;
16959     }
16960
16961     public final int broadcastIntent(IApplicationThread caller,
16962             Intent intent, String resolvedType, IIntentReceiver resultTo,
16963             int resultCode, String resultData, Bundle resultExtras,
16964             String[] requiredPermissions, int appOp, Bundle options,
16965             boolean serialized, boolean sticky, int userId) {
16966         enforceNotIsolatedCaller("broadcastIntent");
16967         synchronized(this) {
16968             intent = verifyBroadcastLocked(intent);
16969
16970             final ProcessRecord callerApp = getRecordForAppLocked(caller);
16971             final int callingPid = Binder.getCallingPid();
16972             final int callingUid = Binder.getCallingUid();
16973             final long origId = Binder.clearCallingIdentity();
16974             int res = broadcastIntentLocked(callerApp,
16975                     callerApp != null ? callerApp.info.packageName : null,
16976                     intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
16977                     requiredPermissions, appOp, null, serialized, sticky,
16978                     callingPid, callingUid, userId);
16979             Binder.restoreCallingIdentity(origId);
16980             return res;
16981         }
16982     }
16983
16984
16985     int broadcastIntentInPackage(String packageName, int uid,
16986             Intent intent, String resolvedType, IIntentReceiver resultTo,
16987             int resultCode, String resultData, Bundle resultExtras,
16988             String requiredPermission, Bundle options, boolean serialized, boolean sticky,
16989             int userId) {
16990         synchronized(this) {
16991             intent = verifyBroadcastLocked(intent);
16992
16993             final long origId = Binder.clearCallingIdentity();
16994             String[] requiredPermissions = requiredPermission == null ? null
16995                     : new String[] {requiredPermission};
16996             int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
16997                     resultTo, resultCode, resultData, resultExtras,
16998                     requiredPermissions, AppOpsManager.OP_NONE, options, serialized,
16999                     sticky, -1, uid, userId);
17000             Binder.restoreCallingIdentity(origId);
17001             return res;
17002         }
17003     }
17004
17005     public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
17006         // Refuse possible leaked file descriptors
17007         if (intent != null && intent.hasFileDescriptors() == true) {
17008             throw new IllegalArgumentException("File descriptors passed in Intent");
17009         }
17010
17011         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17012                 userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
17013
17014         synchronized(this) {
17015             if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
17016                     != PackageManager.PERMISSION_GRANTED) {
17017                 String msg = "Permission Denial: unbroadcastIntent() from pid="
17018                         + Binder.getCallingPid()
17019                         + ", uid=" + Binder.getCallingUid()
17020                         + " requires " + android.Manifest.permission.BROADCAST_STICKY;
17021                 Slog.w(TAG, msg);
17022                 throw new SecurityException(msg);
17023             }
17024             ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
17025             if (stickies != null) {
17026                 ArrayList<Intent> list = stickies.get(intent.getAction());
17027                 if (list != null) {
17028                     int N = list.size();
17029                     int i;
17030                     for (i=0; i<N; i++) {
17031                         if (intent.filterEquals(list.get(i))) {
17032                             list.remove(i);
17033                             break;
17034                         }
17035                     }
17036                     if (list.size() <= 0) {
17037                         stickies.remove(intent.getAction());
17038                     }
17039                 }
17040                 if (stickies.size() <= 0) {
17041                     mStickyBroadcasts.remove(userId);
17042                 }
17043             }
17044         }
17045     }
17046
17047     void backgroundServicesFinishedLocked(int userId) {
17048         for (BroadcastQueue queue : mBroadcastQueues) {
17049             queue.backgroundServicesFinishedLocked(userId);
17050         }
17051     }
17052
17053     public void finishReceiver(IBinder who, int resultCode, String resultData,
17054             Bundle resultExtras, boolean resultAbort, int flags) {
17055         if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
17056
17057         // Refuse possible leaked file descriptors
17058         if (resultExtras != null && resultExtras.hasFileDescriptors()) {
17059             throw new IllegalArgumentException("File descriptors passed in Bundle");
17060         }
17061
17062         final long origId = Binder.clearCallingIdentity();
17063         try {
17064             boolean doNext = false;
17065             BroadcastRecord r;
17066
17067             synchronized(this) {
17068                 BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
17069                         ? mFgBroadcastQueue : mBgBroadcastQueue;
17070                 r = queue.getMatchingOrderedReceiver(who);
17071                 if (r != null) {
17072                     doNext = r.queue.finishReceiverLocked(r, resultCode,
17073                         resultData, resultExtras, resultAbort, true);
17074                 }
17075             }
17076
17077             if (doNext) {
17078                 r.queue.processNextBroadcast(false);
17079             }
17080             trimApplications();
17081         } finally {
17082             Binder.restoreCallingIdentity(origId);
17083         }
17084     }
17085
17086     // =========================================================
17087     // INSTRUMENTATION
17088     // =========================================================
17089
17090     public boolean startInstrumentation(ComponentName className,
17091             String profileFile, int flags, Bundle arguments,
17092             IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
17093             int userId, String abiOverride) {
17094         enforceNotIsolatedCaller("startInstrumentation");
17095         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17096                 userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
17097         // Refuse possible leaked file descriptors
17098         if (arguments != null && arguments.hasFileDescriptors()) {
17099             throw new IllegalArgumentException("File descriptors passed in Bundle");
17100         }
17101
17102         synchronized(this) {
17103             InstrumentationInfo ii = null;
17104             ApplicationInfo ai = null;
17105             try {
17106                 ii = mContext.getPackageManager().getInstrumentationInfo(
17107                     className, STOCK_PM_FLAGS);
17108                 ai = AppGlobals.getPackageManager().getApplicationInfo(
17109                         ii.targetPackage, STOCK_PM_FLAGS, userId);
17110             } catch (PackageManager.NameNotFoundException e) {
17111             } catch (RemoteException e) {
17112             }
17113             if (ii == null) {
17114                 reportStartInstrumentationFailure(watcher, className,
17115                         "Unable to find instrumentation info for: " + className);
17116                 return false;
17117             }
17118             if (ai == null) {
17119                 reportStartInstrumentationFailure(watcher, className,
17120                         "Unable to find instrumentation target package: " + ii.targetPackage);
17121                 return false;
17122             }
17123
17124             int match = mContext.getPackageManager().checkSignatures(
17125                     ii.targetPackage, ii.packageName);
17126             if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
17127                 String msg = "Permission Denial: starting instrumentation "
17128                         + className + " from pid="
17129                         + Binder.getCallingPid()
17130                         + ", uid=" + Binder.getCallingPid()
17131                         + " not allowed because package " + ii.packageName
17132                         + " does not have a signature matching the target "
17133                         + ii.targetPackage;
17134                 reportStartInstrumentationFailure(watcher, className, msg);
17135                 throw new SecurityException(msg);
17136             }
17137
17138             final long origId = Binder.clearCallingIdentity();
17139             // Instrumentation can kill and relaunch even persistent processes
17140             forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
17141                     "start instr");
17142             ProcessRecord app = addAppLocked(ai, false, abiOverride);
17143             app.instrumentationClass = className;
17144             app.instrumentationInfo = ai;
17145             app.instrumentationProfileFile = profileFile;
17146             app.instrumentationArguments = arguments;
17147             app.instrumentationWatcher = watcher;
17148             app.instrumentationUiAutomationConnection = uiAutomationConnection;
17149             app.instrumentationResultClass = className;
17150             Binder.restoreCallingIdentity(origId);
17151         }
17152
17153         return true;
17154     }
17155
17156     /**
17157      * Report errors that occur while attempting to start Instrumentation.  Always writes the
17158      * error to the logs, but if somebody is watching, send the report there too.  This enables
17159      * the "am" command to report errors with more information.
17160      *
17161      * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
17162      * @param cn The component name of the instrumentation.
17163      * @param report The error report.
17164      */
17165     private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
17166             ComponentName cn, String report) {
17167         Slog.w(TAG, report);
17168         try {
17169             if (watcher != null) {
17170                 Bundle results = new Bundle();
17171                 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
17172                 results.putString("Error", report);
17173                 watcher.instrumentationStatus(cn, -1, results);
17174             }
17175         } catch (RemoteException e) {
17176             Slog.w(TAG, e);
17177         }
17178     }
17179
17180     void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
17181         if (app.instrumentationWatcher != null) {
17182             try {
17183                 // NOTE:  IInstrumentationWatcher *must* be oneway here
17184                 app.instrumentationWatcher.instrumentationFinished(
17185                     app.instrumentationClass,
17186                     resultCode,
17187                     results);
17188             } catch (RemoteException e) {
17189             }
17190         }
17191
17192         // Can't call out of the system process with a lock held, so post a message.
17193         if (app.instrumentationUiAutomationConnection != null) {
17194             mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
17195                     app.instrumentationUiAutomationConnection).sendToTarget();
17196         }
17197
17198         app.instrumentationWatcher = null;
17199         app.instrumentationUiAutomationConnection = null;
17200         app.instrumentationClass = null;
17201         app.instrumentationInfo = null;
17202         app.instrumentationProfileFile = null;
17203         app.instrumentationArguments = null;
17204
17205         forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
17206                 "finished inst");
17207     }
17208
17209     public void finishInstrumentation(IApplicationThread target,
17210             int resultCode, Bundle results) {
17211         int userId = UserHandle.getCallingUserId();
17212         // Refuse possible leaked file descriptors
17213         if (results != null && results.hasFileDescriptors()) {
17214             throw new IllegalArgumentException("File descriptors passed in Intent");
17215         }
17216
17217         synchronized(this) {
17218             ProcessRecord app = getRecordForAppLocked(target);
17219             if (app == null) {
17220                 Slog.w(TAG, "finishInstrumentation: no app for " + target);
17221                 return;
17222             }
17223             final long origId = Binder.clearCallingIdentity();
17224             finishInstrumentationLocked(app, resultCode, results);
17225             Binder.restoreCallingIdentity(origId);
17226         }
17227     }
17228
17229     // =========================================================
17230     // CONFIGURATION
17231     // =========================================================
17232
17233     public ConfigurationInfo getDeviceConfigurationInfo() {
17234         ConfigurationInfo config = new ConfigurationInfo();
17235         synchronized (this) {
17236             config.reqTouchScreen = mConfiguration.touchscreen;
17237             config.reqKeyboardType = mConfiguration.keyboard;
17238             config.reqNavigation = mConfiguration.navigation;
17239             if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
17240                     || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
17241                 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
17242             }
17243             if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
17244                     && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
17245                 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
17246             }
17247             config.reqGlEsVersion = GL_ES_VERSION;
17248         }
17249         return config;
17250     }
17251
17252     ActivityStack getFocusedStack() {
17253         return mStackSupervisor.getFocusedStack();
17254     }
17255
17256     @Override
17257     public int getFocusedStackId() throws RemoteException {
17258         ActivityStack focusedStack = getFocusedStack();
17259         if (focusedStack != null) {
17260             return focusedStack.getStackId();
17261         }
17262         return -1;
17263     }
17264
17265     public Configuration getConfiguration() {
17266         Configuration ci;
17267         synchronized(this) {
17268             ci = new Configuration(mConfiguration);
17269             ci.userSetLocale = false;
17270         }
17271         return ci;
17272     }
17273
17274     public void updatePersistentConfiguration(Configuration values) {
17275         enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
17276                 "updateConfiguration()");
17277         enforceWriteSettingsPermission("updateConfiguration()");
17278         if (values == null) {
17279             throw new NullPointerException("Configuration must not be null");
17280         }
17281
17282         synchronized(this) {
17283             final long origId = Binder.clearCallingIdentity();
17284             updateConfigurationLocked(values, null, true, false);
17285             Binder.restoreCallingIdentity(origId);
17286         }
17287     }
17288
17289     private void enforceWriteSettingsPermission(String func) {
17290         int uid = Binder.getCallingUid();
17291         if (uid == Process.ROOT_UID) {
17292             return;
17293         }
17294
17295         if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
17296                 Settings.getPackageNameForUid(mContext, uid), false)) {
17297             return;
17298         }
17299
17300         String msg = "Permission Denial: " + func + " from pid="
17301                 + Binder.getCallingPid()
17302                 + ", uid=" + uid
17303                 + " requires " + android.Manifest.permission.WRITE_SETTINGS;
17304         Slog.w(TAG, msg);
17305         throw new SecurityException(msg);
17306     }
17307
17308     public void updateConfiguration(Configuration values) {
17309         enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
17310                 "updateConfiguration()");
17311
17312         synchronized(this) {
17313             if (values == null && mWindowManager != null) {
17314                 // sentinel: fetch the current configuration from the window manager
17315                 values = mWindowManager.computeNewConfiguration();
17316             }
17317
17318             if (mWindowManager != null) {
17319                 mProcessList.applyDisplaySize(mWindowManager);
17320             }
17321
17322             final long origId = Binder.clearCallingIdentity();
17323             if (values != null) {
17324                 Settings.System.clearConfiguration(values);
17325             }
17326             updateConfigurationLocked(values, null, false, false);
17327             Binder.restoreCallingIdentity(origId);
17328         }
17329     }
17330
17331     /**
17332      * Do either or both things: (1) change the current configuration, and (2)
17333      * make sure the given activity is running with the (now) current
17334      * configuration.  Returns true if the activity has been left running, or
17335      * false if <var>starting</var> is being destroyed to match the new
17336      * configuration.
17337      * @param persistent TODO
17338      */
17339     boolean updateConfigurationLocked(Configuration values,
17340             ActivityRecord starting, boolean persistent, boolean initLocale) {
17341         int changes = 0;
17342
17343         if (values != null) {
17344             Configuration newConfig = new Configuration(mConfiguration);
17345             changes = newConfig.updateFrom(values);
17346             if (changes != 0) {
17347                 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
17348                         "Updating configuration to: " + values);
17349
17350                 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
17351
17352                 if (!initLocale && values.locale != null && values.userSetLocale) {
17353                     final String languageTag = values.locale.toLanguageTag();
17354                     SystemProperties.set("persist.sys.locale", languageTag);
17355                     mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
17356                             values.locale));
17357                 }
17358
17359                 mConfigurationSeq++;
17360                 if (mConfigurationSeq <= 0) {
17361                     mConfigurationSeq = 1;
17362                 }
17363                 newConfig.seq = mConfigurationSeq;
17364                 mConfiguration = newConfig;
17365                 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
17366                 mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId);
17367                 //mUsageStatsService.noteStartConfig(newConfig);
17368
17369                 final Configuration configCopy = new Configuration(mConfiguration);
17370
17371                 // TODO: If our config changes, should we auto dismiss any currently
17372                 // showing dialogs?
17373                 mShowDialogs = shouldShowDialogs(newConfig);
17374
17375                 AttributeCache ac = AttributeCache.instance();
17376                 if (ac != null) {
17377                     ac.updateConfiguration(configCopy);
17378                 }
17379
17380                 // Make sure all resources in our process are updated
17381                 // right now, so that anyone who is going to retrieve
17382                 // resource values after we return will be sure to get
17383                 // the new ones.  This is especially important during
17384                 // boot, where the first config change needs to guarantee
17385                 // all resources have that config before following boot
17386                 // code is executed.
17387                 mSystemThread.applyConfigurationToResources(configCopy);
17388
17389                 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
17390                     Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
17391                     msg.obj = new Configuration(configCopy);
17392                     mHandler.sendMessage(msg);
17393                 }
17394
17395                 for (int i=mLruProcesses.size()-1; i>=0; i--) {
17396                     ProcessRecord app = mLruProcesses.get(i);
17397                     try {
17398                         if (app.thread != null) {
17399                             if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
17400                                     + app.processName + " new config " + mConfiguration);
17401                             app.thread.scheduleConfigurationChanged(configCopy);
17402                         }
17403                     } catch (Exception e) {
17404                     }
17405                 }
17406                 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
17407                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17408                         | Intent.FLAG_RECEIVER_REPLACE_PENDING
17409                         | Intent.FLAG_RECEIVER_FOREGROUND);
17410                 broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
17411                         null, AppOpsManager.OP_NONE, null, false, false,
17412                         MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17413                 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
17414                     intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
17415                     intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
17416                     if (!mProcessesReady) {
17417                         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17418                     }
17419                     broadcastIntentLocked(null, null, intent,
17420                             null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17421                             null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17422                 }
17423             }
17424         }
17425
17426         boolean kept = true;
17427         final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
17428         // mainStack is null during startup.
17429         if (mainStack != null) {
17430             if (changes != 0 && starting == null) {
17431                 // If the configuration changed, and the caller is not already
17432                 // in the process of starting an activity, then find the top
17433                 // activity to check if its configuration needs to change.
17434                 starting = mainStack.topRunningActivityLocked(null);
17435             }
17436
17437             if (starting != null) {
17438                 kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
17439                 // And we need to make sure at this point that all other activities
17440                 // are made visible with the correct configuration.
17441                 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
17442             }
17443         }
17444
17445         if (values != null && mWindowManager != null) {
17446             mWindowManager.setNewConfiguration(mConfiguration);
17447         }
17448
17449         return kept;
17450     }
17451
17452     /**
17453      * Decide based on the configuration whether we should shouw the ANR,
17454      * crash, etc dialogs.  The idea is that if there is no affordnace to
17455      * press the on-screen buttons, we shouldn't show the dialog.
17456      *
17457      * A thought: SystemUI might also want to get told about this, the Power
17458      * dialog / global actions also might want different behaviors.
17459      */
17460     private static final boolean shouldShowDialogs(Configuration config) {
17461         return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
17462                 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
17463                 && config.navigation == Configuration.NAVIGATION_NONAV);
17464     }
17465
17466     @Override
17467     public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
17468         synchronized (this) {
17469             ActivityRecord srec = ActivityRecord.forTokenLocked(token);
17470             if (srec != null) {
17471                 return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
17472             }
17473         }
17474         return false;
17475     }
17476
17477     public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
17478             Intent resultData) {
17479
17480         synchronized (this) {
17481             final ActivityRecord r = ActivityRecord.forTokenLocked(token);
17482             if (r != null) {
17483                 return r.task.stack.navigateUpToLocked(r, destIntent, resultCode, resultData);
17484             }
17485             return false;
17486         }
17487     }
17488
17489     public int getLaunchedFromUid(IBinder activityToken) {
17490         ActivityRecord srec;
17491         synchronized (this) {
17492             srec = ActivityRecord.forTokenLocked(activityToken);
17493         }
17494         if (srec == null) {
17495             return -1;
17496         }
17497         return srec.launchedFromUid;
17498     }
17499
17500     public String getLaunchedFromPackage(IBinder activityToken) {
17501         ActivityRecord srec;
17502         synchronized (this) {
17503             srec = ActivityRecord.forTokenLocked(activityToken);
17504         }
17505         if (srec == null) {
17506             return null;
17507         }
17508         return srec.launchedFromPackage;
17509     }
17510
17511     // =========================================================
17512     // LIFETIME MANAGEMENT
17513     // =========================================================
17514
17515     // Returns which broadcast queue the app is the current [or imminent] receiver
17516     // on, or 'null' if the app is not an active broadcast recipient.
17517     private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
17518         BroadcastRecord r = app.curReceiver;
17519         if (r != null) {
17520             return r.queue;
17521         }
17522
17523         // It's not the current receiver, but it might be starting up to become one
17524         synchronized (this) {
17525             for (BroadcastQueue queue : mBroadcastQueues) {
17526                 r = queue.mPendingBroadcast;
17527                 if (r != null && r.curApp == app) {
17528                     // found it; report which queue it's in
17529                     return queue;
17530                 }
17531             }
17532         }
17533
17534         return null;
17535     }
17536
17537     Association startAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
17538             ComponentName targetComponent, String targetProcess) {
17539         if (!mTrackingAssociations) {
17540             return null;
17541         }
17542         ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
17543                 = mAssociations.get(targetUid);
17544         if (components == null) {
17545             components = new ArrayMap<>();
17546             mAssociations.put(targetUid, components);
17547         }
17548         SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
17549         if (sourceUids == null) {
17550             sourceUids = new SparseArray<>();
17551             components.put(targetComponent, sourceUids);
17552         }
17553         ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
17554         if (sourceProcesses == null) {
17555             sourceProcesses = new ArrayMap<>();
17556             sourceUids.put(sourceUid, sourceProcesses);
17557         }
17558         Association ass = sourceProcesses.get(sourceProcess);
17559         if (ass == null) {
17560             ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
17561                     targetProcess);
17562             sourceProcesses.put(sourceProcess, ass);
17563         }
17564         ass.mCount++;
17565         ass.mNesting++;
17566         if (ass.mNesting == 1) {
17567             ass.mStartTime = SystemClock.uptimeMillis();
17568         }
17569         return ass;
17570     }
17571
17572     void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
17573             ComponentName targetComponent) {
17574         if (!mTrackingAssociations) {
17575             return;
17576         }
17577         ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
17578                 = mAssociations.get(targetUid);
17579         if (components == null) {
17580             return;
17581         }
17582         SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
17583         if (sourceUids == null) {
17584             return;
17585         }
17586         ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
17587         if (sourceProcesses == null) {
17588             return;
17589         }
17590         Association ass = sourceProcesses.get(sourceProcess);
17591         if (ass == null || ass.mNesting <= 0) {
17592             return;
17593         }
17594         ass.mNesting--;
17595         if (ass.mNesting == 0) {
17596             ass.mTime += SystemClock.uptimeMillis() - ass.mStartTime;
17597         }
17598     }
17599
17600     private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
17601             boolean doingAll, long now) {
17602         if (mAdjSeq == app.adjSeq) {
17603             // This adjustment has already been computed.
17604             return app.curRawAdj;
17605         }
17606
17607         if (app.thread == null) {
17608             app.adjSeq = mAdjSeq;
17609             app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17610             app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17611             return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
17612         }
17613
17614         app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
17615         app.adjSource = null;
17616         app.adjTarget = null;
17617         app.empty = false;
17618         app.cached = false;
17619
17620         final int activitiesSize = app.activities.size();
17621
17622         if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
17623             // The max adjustment doesn't allow this app to be anything
17624             // below foreground, so it is not worth doing work for it.
17625             app.adjType = "fixed";
17626             app.adjSeq = mAdjSeq;
17627             app.curRawAdj = app.maxAdj;
17628             app.foregroundActivities = false;
17629             app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
17630             app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
17631             // System processes can do UI, and when they do we want to have
17632             // them trim their memory after the user leaves the UI.  To
17633             // facilitate this, here we need to determine whether or not it
17634             // is currently showing UI.
17635             app.systemNoUi = true;
17636             if (app == TOP_APP) {
17637                 app.systemNoUi = false;
17638             } else if (activitiesSize > 0) {
17639                 for (int j = 0; j < activitiesSize; j++) {
17640                     final ActivityRecord r = app.activities.get(j);
17641                     if (r.visible) {
17642                         app.systemNoUi = false;
17643                     }
17644                 }
17645             }
17646             if (!app.systemNoUi) {
17647                 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
17648             }
17649             return (app.curAdj=app.maxAdj);
17650         }
17651
17652         app.systemNoUi = false;
17653
17654         final int PROCESS_STATE_TOP = mTopProcessState;
17655
17656         // Determine the importance of the process, starting with most
17657         // important to least, and assign an appropriate OOM adjustment.
17658         int adj;
17659         int schedGroup;
17660         int procState;
17661         boolean foregroundActivities = false;
17662         BroadcastQueue queue;
17663         if (app == TOP_APP) {
17664             // The last app on the list is the foreground app.
17665             adj = ProcessList.FOREGROUND_APP_ADJ;
17666             schedGroup = Process.THREAD_GROUP_DEFAULT;
17667             app.adjType = "top-activity";
17668             foregroundActivities = true;
17669             procState = PROCESS_STATE_TOP;
17670         } else if (app.instrumentationClass != null) {
17671             // Don't want to kill running instrumentation.
17672             adj = ProcessList.FOREGROUND_APP_ADJ;
17673             schedGroup = Process.THREAD_GROUP_DEFAULT;
17674             app.adjType = "instrumentation";
17675             procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
17676         } else if ((queue = isReceivingBroadcast(app)) != null) {
17677             // An app that is currently receiving a broadcast also
17678             // counts as being in the foreground for OOM killer purposes.
17679             // It's placed in a sched group based on the nature of the
17680             // broadcast as reflected by which queue it's active in.
17681             adj = ProcessList.FOREGROUND_APP_ADJ;
17682             schedGroup = (queue == mFgBroadcastQueue)
17683                     ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
17684             app.adjType = "broadcast";
17685             procState = ActivityManager.PROCESS_STATE_RECEIVER;
17686         } else if (app.executingServices.size() > 0) {
17687             // An app that is currently executing a service callback also
17688             // counts as being in the foreground.
17689             adj = ProcessList.FOREGROUND_APP_ADJ;
17690             schedGroup = app.execServicesFg ?
17691                     Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
17692             app.adjType = "exec-service";
17693             procState = ActivityManager.PROCESS_STATE_SERVICE;
17694             //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
17695         } else {
17696             // As far as we know the process is empty.  We may change our mind later.
17697             schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17698             // At this point we don't actually know the adjustment.  Use the cached adj
17699             // value that the caller wants us to.
17700             adj = cachedAdj;
17701             procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17702             app.cached = true;
17703             app.empty = true;
17704             app.adjType = "cch-empty";
17705         }
17706
17707         // Examine all activities if not already foreground.
17708         if (!foregroundActivities && activitiesSize > 0) {
17709             for (int j = 0; j < activitiesSize; j++) {
17710                 final ActivityRecord r = app.activities.get(j);
17711                 if (r.app != app) {
17712                     Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
17713                             + app + "?!? Using " + r.app + " instead.");
17714                     continue;
17715                 }
17716                 if (r.visible) {
17717                     // App has a visible activity; only upgrade adjustment.
17718                     if (adj > ProcessList.VISIBLE_APP_ADJ) {
17719                         adj = ProcessList.VISIBLE_APP_ADJ;
17720                         app.adjType = "visible";
17721                     }
17722                     if (procState > PROCESS_STATE_TOP) {
17723                         procState = PROCESS_STATE_TOP;
17724                     }
17725                     schedGroup = Process.THREAD_GROUP_DEFAULT;
17726                     app.cached = false;
17727                     app.empty = false;
17728                     foregroundActivities = true;
17729                     break;
17730                 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
17731                     if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17732                         adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17733                         app.adjType = "pausing";
17734                     }
17735                     if (procState > PROCESS_STATE_TOP) {
17736                         procState = PROCESS_STATE_TOP;
17737                     }
17738                     schedGroup = Process.THREAD_GROUP_DEFAULT;
17739                     app.cached = false;
17740                     app.empty = false;
17741                     foregroundActivities = true;
17742                 } else if (r.state == ActivityState.STOPPING) {
17743                     if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17744                         adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17745                         app.adjType = "stopping";
17746                     }
17747                     // For the process state, we will at this point consider the
17748                     // process to be cached.  It will be cached either as an activity
17749                     // or empty depending on whether the activity is finishing.  We do
17750                     // this so that we can treat the process as cached for purposes of
17751                     // memory trimming (determing current memory level, trim command to
17752                     // send to process) since there can be an arbitrary number of stopping
17753                     // processes and they should soon all go into the cached state.
17754                     if (!r.finishing) {
17755                         if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
17756                             procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
17757                         }
17758                     }
17759                     app.cached = false;
17760                     app.empty = false;
17761                     foregroundActivities = true;
17762                 } else {
17763                     if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
17764                         procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
17765                         app.adjType = "cch-act";
17766                     }
17767                 }
17768             }
17769         }
17770
17771         if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17772             if (app.foregroundServices) {
17773                 // The user is aware of this app, so make it visible.
17774                 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17775                 procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
17776                 app.cached = false;
17777                 app.adjType = "fg-service";
17778                 schedGroup = Process.THREAD_GROUP_DEFAULT;
17779             } else if (app.forcingToForeground != null) {
17780                 // The user is aware of this app, so make it visible.
17781                 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17782                 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17783                 app.cached = false;
17784                 app.adjType = "force-fg";
17785                 app.adjSource = app.forcingToForeground;
17786                 schedGroup = Process.THREAD_GROUP_DEFAULT;
17787             }
17788         }
17789
17790         if (app == mHeavyWeightProcess) {
17791             if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
17792                 // We don't want to kill the current heavy-weight process.
17793                 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
17794                 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17795                 app.cached = false;
17796                 app.adjType = "heavy";
17797             }
17798             if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
17799                 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
17800             }
17801         }
17802
17803         if (app == mHomeProcess) {
17804             if (adj > ProcessList.HOME_APP_ADJ) {
17805                 // This process is hosting what we currently consider to be the
17806                 // home app, so we don't want to let it go into the background.
17807                 adj = ProcessList.HOME_APP_ADJ;
17808                 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17809                 app.cached = false;
17810                 app.adjType = "home";
17811             }
17812             if (procState > ActivityManager.PROCESS_STATE_HOME) {
17813                 procState = ActivityManager.PROCESS_STATE_HOME;
17814             }
17815         }
17816
17817         if (app == mPreviousProcess && app.activities.size() > 0) {
17818             if (adj > ProcessList.PREVIOUS_APP_ADJ) {
17819                 // This was the previous process that showed UI to the user.
17820                 // We want to try to keep it around more aggressively, to give
17821                 // a good experience around switching between two apps.
17822                 adj = ProcessList.PREVIOUS_APP_ADJ;
17823                 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17824                 app.cached = false;
17825                 app.adjType = "previous";
17826             }
17827             if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
17828                 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
17829             }
17830         }
17831
17832         if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
17833                 + " reason=" + app.adjType);
17834
17835         // By default, we use the computed adjustment.  It may be changed if
17836         // there are applications dependent on our services or providers, but
17837         // this gives us a baseline and makes sure we don't get into an
17838         // infinite recursion.
17839         app.adjSeq = mAdjSeq;
17840         app.curRawAdj = adj;
17841         app.hasStartedServices = false;
17842
17843         if (mBackupTarget != null && app == mBackupTarget.app) {
17844             // If possible we want to avoid killing apps while they're being backed up
17845             if (adj > ProcessList.BACKUP_APP_ADJ) {
17846                 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
17847                 adj = ProcessList.BACKUP_APP_ADJ;
17848                 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
17849                     procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
17850                 }
17851                 app.adjType = "backup";
17852                 app.cached = false;
17853             }
17854             if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
17855                 procState = ActivityManager.PROCESS_STATE_BACKUP;
17856             }
17857         }
17858
17859         boolean mayBeTop = false;
17860
17861         for (int is = app.services.size()-1;
17862                 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17863                         || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17864                         || procState > ActivityManager.PROCESS_STATE_TOP);
17865                 is--) {
17866             ServiceRecord s = app.services.valueAt(is);
17867             if (s.startRequested) {
17868                 app.hasStartedServices = true;
17869                 if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
17870                     procState = ActivityManager.PROCESS_STATE_SERVICE;
17871                 }
17872                 if (app.hasShownUi && app != mHomeProcess) {
17873                     // If this process has shown some UI, let it immediately
17874                     // go to the LRU list because it may be pretty heavy with
17875                     // UI stuff.  We'll tag it with a label just to help
17876                     // debug and understand what is going on.
17877                     if (adj > ProcessList.SERVICE_ADJ) {
17878                         app.adjType = "cch-started-ui-services";
17879                     }
17880                 } else {
17881                     if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
17882                         // This service has seen some activity within
17883                         // recent memory, so we will keep its process ahead
17884                         // of the background processes.
17885                         if (adj > ProcessList.SERVICE_ADJ) {
17886                             adj = ProcessList.SERVICE_ADJ;
17887                             app.adjType = "started-services";
17888                             app.cached = false;
17889                         }
17890                     }
17891                     // If we have let the service slide into the background
17892                     // state, still have some text describing what it is doing
17893                     // even though the service no longer has an impact.
17894                     if (adj > ProcessList.SERVICE_ADJ) {
17895                         app.adjType = "cch-started-services";
17896                     }
17897                 }
17898             }
17899             for (int conni = s.connections.size()-1;
17900                     conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17901                             || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17902                             || procState > ActivityManager.PROCESS_STATE_TOP);
17903                     conni--) {
17904                 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
17905                 for (int i = 0;
17906                         i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
17907                                 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17908                                 || procState > ActivityManager.PROCESS_STATE_TOP);
17909                         i++) {
17910                     // XXX should compute this based on the max of
17911                     // all connected clients.
17912                     ConnectionRecord cr = clist.get(i);
17913                     if (cr.binding.client == app) {
17914                         // Binding to ourself is not interesting.
17915                         continue;
17916                     }
17917                     if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
17918                         ProcessRecord client = cr.binding.client;
17919                         int clientAdj = computeOomAdjLocked(client, cachedAdj,
17920                                 TOP_APP, doingAll, now);
17921                         int clientProcState = client.curProcState;
17922                         if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
17923                             // If the other app is cached for any reason, for purposes here
17924                             // we are going to consider it empty.  The specific cached state
17925                             // doesn't propagate except under certain conditions.
17926                             clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17927                         }
17928                         String adjType = null;
17929                         if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
17930                             // Not doing bind OOM management, so treat
17931                             // this guy more like a started service.
17932                             if (app.hasShownUi && app != mHomeProcess) {
17933                                 // If this process has shown some UI, let it immediately
17934                                 // go to the LRU list because it may be pretty heavy with
17935                                 // UI stuff.  We'll tag it with a label just to help
17936                                 // debug and understand what is going on.
17937                                 if (adj > clientAdj) {
17938                                     adjType = "cch-bound-ui-services";
17939                                 }
17940                                 app.cached = false;
17941                                 clientAdj = adj;
17942                                 clientProcState = procState;
17943                             } else {
17944                                 if (now >= (s.lastActivity
17945                                         + ActiveServices.MAX_SERVICE_INACTIVITY)) {
17946                                     // This service has not seen activity within
17947                                     // recent memory, so allow it to drop to the
17948                                     // LRU list if there is no other reason to keep
17949                                     // it around.  We'll also tag it with a label just
17950                                     // to help debug and undertand what is going on.
17951                                     if (adj > clientAdj) {
17952                                         adjType = "cch-bound-services";
17953                                     }
17954                                     clientAdj = adj;
17955                                 }
17956                             }
17957                         }
17958                         if (adj > clientAdj) {
17959                             // If this process has recently shown UI, and
17960                             // the process that is binding to it is less
17961                             // important than being visible, then we don't
17962                             // care about the binding as much as we care
17963                             // about letting this process get into the LRU
17964                             // list to be killed and restarted if needed for
17965                             // memory.
17966                             if (app.hasShownUi && app != mHomeProcess
17967                                     && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17968                                 adjType = "cch-bound-ui-services";
17969                             } else {
17970                                 if ((cr.flags&(Context.BIND_ABOVE_CLIENT
17971                                         |Context.BIND_IMPORTANT)) != 0) {
17972                                     adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
17973                                             ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
17974                                 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
17975                                         && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
17976                                         && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17977                                     adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17978                                 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
17979                                     adj = clientAdj;
17980                                 } else {
17981                                     if (adj > ProcessList.VISIBLE_APP_ADJ) {
17982                                         adj = ProcessList.VISIBLE_APP_ADJ;
17983                                     }
17984                                 }
17985                                 if (!client.cached) {
17986                                     app.cached = false;
17987                                 }
17988                                 adjType = "service";
17989                             }
17990                         }
17991                         if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
17992                             if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
17993                                 schedGroup = Process.THREAD_GROUP_DEFAULT;
17994                             }
17995                             if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
17996                                 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
17997                                     // Special handling of clients who are in the top state.
17998                                     // We *may* want to consider this process to be in the
17999                                     // top state as well, but only if there is not another
18000                                     // reason for it to be running.  Being on the top is a
18001                                     // special state, meaning you are specifically running
18002                                     // for the current top app.  If the process is already
18003                                     // running in the background for some other reason, it
18004                                     // is more important to continue considering it to be
18005                                     // in the background state.
18006                                     mayBeTop = true;
18007                                     clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18008                                 } else {
18009                                     // Special handling for above-top states (persistent
18010                                     // processes).  These should not bring the current process
18011                                     // into the top state, since they are not on top.  Instead
18012                                     // give them the best state after that.
18013                                     if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
18014                                         clientProcState =
18015                                                 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18016                                     } else if (mWakefulness
18017                                                     == PowerManagerInternal.WAKEFULNESS_AWAKE &&
18018                                             (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
18019                                                     != 0) {
18020                                         clientProcState =
18021                                                 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18022                                     } else {
18023                                         clientProcState =
18024                                                 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18025                                     }
18026                                 }
18027                             }
18028                         } else {
18029                             if (clientProcState <
18030                                     ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
18031                                 clientProcState =
18032                                         ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
18033                             }
18034                         }
18035                         if (procState > clientProcState) {
18036                             procState = clientProcState;
18037                         }
18038                         if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
18039                                 && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
18040                             app.pendingUiClean = true;
18041                         }
18042                         if (adjType != null) {
18043                             app.adjType = adjType;
18044                             app.adjTypeCode = ActivityManager.RunningAppProcessInfo
18045                                     .REASON_SERVICE_IN_USE;
18046                             app.adjSource = cr.binding.client;
18047                             app.adjSourceProcState = clientProcState;
18048                             app.adjTarget = s.name;
18049                         }
18050                     }
18051                     if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
18052                         app.treatLikeActivity = true;
18053                     }
18054                     final ActivityRecord a = cr.activity;
18055                     if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
18056                         if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
18057                                 (a.visible || a.state == ActivityState.RESUMED
18058                                  || a.state == ActivityState.PAUSING)) {
18059                             adj = ProcessList.FOREGROUND_APP_ADJ;
18060                             if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
18061                                 schedGroup = Process.THREAD_GROUP_DEFAULT;
18062                             }
18063                             app.cached = false;
18064                             app.adjType = "service";
18065                             app.adjTypeCode = ActivityManager.RunningAppProcessInfo
18066                                     .REASON_SERVICE_IN_USE;
18067                             app.adjSource = a;
18068                             app.adjSourceProcState = procState;
18069                             app.adjTarget = s.name;
18070                         }
18071                     }
18072                 }
18073             }
18074         }
18075
18076         for (int provi = app.pubProviders.size()-1;
18077                 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18078                         || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
18079                         || procState > ActivityManager.PROCESS_STATE_TOP);
18080                 provi--) {
18081             ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
18082             for (int i = cpr.connections.size()-1;
18083                     i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18084                             || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
18085                             || procState > ActivityManager.PROCESS_STATE_TOP);
18086                     i--) {
18087                 ContentProviderConnection conn = cpr.connections.get(i);
18088                 ProcessRecord client = conn.client;
18089                 if (client == app) {
18090                     // Being our own client is not interesting.
18091                     continue;
18092                 }
18093                 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
18094                 int clientProcState = client.curProcState;
18095                 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
18096                     // If the other app is cached for any reason, for purposes here
18097                     // we are going to consider it empty.
18098                     clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18099                 }
18100                 if (adj > clientAdj) {
18101                     if (app.hasShownUi && app != mHomeProcess
18102                             && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18103                         app.adjType = "cch-ui-provider";
18104                     } else {
18105                         adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
18106                                 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
18107                         app.adjType = "provider";
18108                     }
18109                     app.cached &= client.cached;
18110                     app.adjTypeCode = ActivityManager.RunningAppProcessInfo
18111                             .REASON_PROVIDER_IN_USE;
18112                     app.adjSource = client;
18113                     app.adjSourceProcState = clientProcState;
18114                     app.adjTarget = cpr.name;
18115                 }
18116                 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
18117                     if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
18118                         // Special handling of clients who are in the top state.
18119                         // We *may* want to consider this process to be in the
18120                         // top state as well, but only if there is not another
18121                         // reason for it to be running.  Being on the top is a
18122                         // special state, meaning you are specifically running
18123                         // for the current top app.  If the process is already
18124                         // running in the background for some other reason, it
18125                         // is more important to continue considering it to be
18126                         // in the background state.
18127                         mayBeTop = true;
18128                         clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18129                     } else {
18130                         // Special handling for above-top states (persistent
18131                         // processes).  These should not bring the current process
18132                         // into the top state, since they are not on top.  Instead
18133                         // give them the best state after that.
18134                         clientProcState =
18135                                 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18136                     }
18137                 }
18138                 if (procState > clientProcState) {
18139                     procState = clientProcState;
18140                 }
18141                 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
18142                     schedGroup = Process.THREAD_GROUP_DEFAULT;
18143                 }
18144             }
18145             // If the provider has external (non-framework) process
18146             // dependencies, ensure that its adjustment is at least
18147             // FOREGROUND_APP_ADJ.
18148             if (cpr.hasExternalProcessHandles()) {
18149                 if (adj > ProcessList.FOREGROUND_APP_ADJ) {
18150                     adj = ProcessList.FOREGROUND_APP_ADJ;
18151                     schedGroup = Process.THREAD_GROUP_DEFAULT;
18152                     app.cached = false;
18153                     app.adjType = "provider";
18154                     app.adjTarget = cpr.name;
18155                 }
18156                 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
18157                     procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18158                 }
18159             }
18160         }
18161
18162         if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
18163             // A client of one of our services or providers is in the top state.  We
18164             // *may* want to be in the top state, but not if we are already running in
18165             // the background for some other reason.  For the decision here, we are going
18166             // to pick out a few specific states that we want to remain in when a client
18167             // is top (states that tend to be longer-term) and otherwise allow it to go
18168             // to the top state.
18169             switch (procState) {
18170                 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
18171                 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
18172                 case ActivityManager.PROCESS_STATE_SERVICE:
18173                     // These all are longer-term states, so pull them up to the top
18174                     // of the background states, but not all the way to the top state.
18175                     procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18176                     break;
18177                 default:
18178                     // Otherwise, top is a better choice, so take it.
18179                     procState = ActivityManager.PROCESS_STATE_TOP;
18180                     break;
18181             }
18182         }
18183
18184         if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
18185             if (app.hasClientActivities) {
18186                 // This is a cached process, but with client activities.  Mark it so.
18187                 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
18188                 app.adjType = "cch-client-act";
18189             } else if (app.treatLikeActivity) {
18190                 // This is a cached process, but somebody wants us to treat it like it has
18191                 // an activity, okay!
18192                 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
18193                 app.adjType = "cch-as-act";
18194             }
18195         }
18196
18197         if (adj == ProcessList.SERVICE_ADJ) {
18198             if (doingAll) {
18199                 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
18200                 mNewNumServiceProcs++;
18201                 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
18202                 if (!app.serviceb) {
18203                     // This service isn't far enough down on the LRU list to
18204                     // normally be a B service, but if we are low on RAM and it
18205                     // is large we want to force it down since we would prefer to
18206                     // keep launcher over it.
18207                     if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
18208                             && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
18209                         app.serviceHighRam = true;
18210                         app.serviceb = true;
18211                         //Slog.i(TAG, "ADJ " + app + " high ram!");
18212                     } else {
18213                         mNewNumAServiceProcs++;
18214                         //Slog.i(TAG, "ADJ " + app + " not high ram!");
18215                     }
18216                 } else {
18217                     app.serviceHighRam = false;
18218                 }
18219             }
18220             if (app.serviceb) {
18221                 adj = ProcessList.SERVICE_B_ADJ;
18222             }
18223         }
18224
18225         app.curRawAdj = adj;
18226
18227         //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
18228         //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
18229         if (adj > app.maxAdj) {
18230             adj = app.maxAdj;
18231             if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
18232                 schedGroup = Process.THREAD_GROUP_DEFAULT;
18233             }
18234         }
18235
18236         // Do final modification to adj.  Everything we do between here and applying
18237         // the final setAdj must be done in this function, because we will also use
18238         // it when computing the final cached adj later.  Note that we don't need to
18239         // worry about this for max adj above, since max adj will always be used to
18240         // keep it out of the cached vaues.
18241         app.curAdj = app.modifyRawOomAdj(adj);
18242         app.curSchedGroup = schedGroup;
18243         app.curProcState = procState;
18244         app.foregroundActivities = foregroundActivities;
18245
18246         return app.curRawAdj;
18247     }
18248
18249     /**
18250      * Record new PSS sample for a process.
18251      */
18252     void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long now) {
18253         EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024);
18254         proc.lastPssTime = now;
18255         proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
18256         if (DEBUG_PSS) Slog.d(TAG_PSS,
18257                 "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
18258                 + " state=" + ProcessList.makeProcStateString(procState));
18259         if (proc.initialIdlePss == 0) {
18260             proc.initialIdlePss = pss;
18261         }
18262         proc.lastPss = pss;
18263         if (procState >= ActivityManager.PROCESS_STATE_HOME) {
18264             proc.lastCachedPss = pss;
18265         }
18266
18267         final SparseArray<Pair<Long, String>> watchUids
18268                 = mMemWatchProcesses.getMap().get(proc.processName);
18269         Long check = null;
18270         if (watchUids != null) {
18271             Pair<Long, String> val = watchUids.get(proc.uid);
18272             if (val == null) {
18273                 val = watchUids.get(0);
18274             }
18275             if (val != null) {
18276                 check = val.first;
18277             }
18278         }
18279         if (check != null) {
18280             if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
18281                 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
18282                 if (!isDebuggable) {
18283                     if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
18284                         isDebuggable = true;
18285                     }
18286                 }
18287                 if (isDebuggable) {
18288                     Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
18289                     final ProcessRecord myProc = proc;
18290                     final File heapdumpFile = DumpHeapProvider.getJavaFile();
18291                     mMemWatchDumpProcName = proc.processName;
18292                     mMemWatchDumpFile = heapdumpFile.toString();
18293                     mMemWatchDumpPid = proc.pid;
18294                     mMemWatchDumpUid = proc.uid;
18295                     BackgroundThread.getHandler().post(new Runnable() {
18296                         @Override
18297                         public void run() {
18298                             revokeUriPermission(ActivityThread.currentActivityThread()
18299                                             .getApplicationThread(),
18300                                     DumpHeapActivity.JAVA_URI,
18301                                     Intent.FLAG_GRANT_READ_URI_PERMISSION
18302                                             | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
18303                                     UserHandle.myUserId());
18304                             ParcelFileDescriptor fd = null;
18305                             try {
18306                                 heapdumpFile.delete();
18307                                 fd = ParcelFileDescriptor.open(heapdumpFile,
18308                                         ParcelFileDescriptor.MODE_CREATE |
18309                                                 ParcelFileDescriptor.MODE_TRUNCATE |
18310                                                 ParcelFileDescriptor.MODE_WRITE_ONLY |
18311                                                 ParcelFileDescriptor.MODE_APPEND);
18312                                 IApplicationThread thread = myProc.thread;
18313                                 if (thread != null) {
18314                                     try {
18315                                         if (DEBUG_PSS) Slog.d(TAG_PSS,
18316                                                 "Requesting dump heap from "
18317                                                 + myProc + " to " + heapdumpFile);
18318                                         thread.dumpHeap(true, heapdumpFile.toString(), fd);
18319                                     } catch (RemoteException e) {
18320                                     }
18321                                 }
18322                             } catch (FileNotFoundException e) {
18323                                 e.printStackTrace();
18324                             } finally {
18325                                 if (fd != null) {
18326                                     try {
18327                                         fd.close();
18328                                     } catch (IOException e) {
18329                                     }
18330                                 }
18331                             }
18332                         }
18333                     });
18334                 } else {
18335                     Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
18336                             + ", but debugging not enabled");
18337                 }
18338             }
18339         }
18340     }
18341
18342     /**
18343      * Schedule PSS collection of a process.
18344      */
18345     void requestPssLocked(ProcessRecord proc, int procState) {
18346         if (mPendingPssProcesses.contains(proc)) {
18347             return;
18348         }
18349         if (mPendingPssProcesses.size() == 0) {
18350             mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
18351         }
18352         if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
18353         proc.pssProcState = procState;
18354         mPendingPssProcesses.add(proc);
18355     }
18356
18357     /**
18358      * Schedule PSS collection of all processes.
18359      */
18360     void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
18361         if (!always) {
18362             if (now < (mLastFullPssTime +
18363                     (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
18364                 return;
18365             }
18366         }
18367         if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
18368         mLastFullPssTime = now;
18369         mFullPssPending = true;
18370         mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
18371         mPendingPssProcesses.clear();
18372         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
18373             ProcessRecord app = mLruProcesses.get(i);
18374             if (app.thread == null
18375                     || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
18376                 continue;
18377             }
18378             if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
18379                 app.pssProcState = app.setProcState;
18380                 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
18381                         mTestPssMode, isSleeping(), now);
18382                 mPendingPssProcesses.add(app);
18383             }
18384         }
18385         mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
18386     }
18387
18388     public void setTestPssMode(boolean enabled) {
18389         synchronized (this) {
18390             mTestPssMode = enabled;
18391             if (enabled) {
18392                 // Whenever we enable the mode, we want to take a snapshot all of current
18393                 // process mem use.
18394                 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
18395             }
18396         }
18397     }
18398
18399     /**
18400      * Ask a given process to GC right now.
18401      */
18402     final void performAppGcLocked(ProcessRecord app) {
18403         try {
18404             app.lastRequestedGc = SystemClock.uptimeMillis();
18405             if (app.thread != null) {
18406                 if (app.reportLowMemory) {
18407                     app.reportLowMemory = false;
18408                     app.thread.scheduleLowMemory();
18409                 } else {
18410                     app.thread.processInBackground();
18411                 }
18412             }
18413         } catch (Exception e) {
18414             // whatever.
18415         }
18416     }
18417
18418     /**
18419      * Returns true if things are idle enough to perform GCs.
18420      */
18421     private final boolean canGcNowLocked() {
18422         boolean processingBroadcasts = false;
18423         for (BroadcastQueue q : mBroadcastQueues) {
18424             if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
18425                 processingBroadcasts = true;
18426             }
18427         }
18428         return !processingBroadcasts
18429                 && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
18430     }
18431
18432     /**
18433      * Perform GCs on all processes that are waiting for it, but only
18434      * if things are idle.
18435      */
18436     final void performAppGcsLocked() {
18437         final int N = mProcessesToGc.size();
18438         if (N <= 0) {
18439             return;
18440         }
18441         if (canGcNowLocked()) {
18442             while (mProcessesToGc.size() > 0) {
18443                 ProcessRecord proc = mProcessesToGc.remove(0);
18444                 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
18445                     if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
18446                             <= SystemClock.uptimeMillis()) {
18447                         // To avoid spamming the system, we will GC processes one
18448                         // at a time, waiting a few seconds between each.
18449                         performAppGcLocked(proc);
18450                         scheduleAppGcsLocked();
18451                         return;
18452                     } else {
18453                         // It hasn't been long enough since we last GCed this
18454                         // process...  put it in the list to wait for its time.
18455                         addProcessToGcListLocked(proc);
18456                         break;
18457                     }
18458                 }
18459             }
18460
18461             scheduleAppGcsLocked();
18462         }
18463     }
18464
18465     /**
18466      * If all looks good, perform GCs on all processes waiting for them.
18467      */
18468     final void performAppGcsIfAppropriateLocked() {
18469         if (canGcNowLocked()) {
18470             performAppGcsLocked();
18471             return;
18472         }
18473         // Still not idle, wait some more.
18474         scheduleAppGcsLocked();
18475     }
18476
18477     /**
18478      * Schedule the execution of all pending app GCs.
18479      */
18480     final void scheduleAppGcsLocked() {
18481         mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
18482
18483         if (mProcessesToGc.size() > 0) {
18484             // Schedule a GC for the time to the next process.
18485             ProcessRecord proc = mProcessesToGc.get(0);
18486             Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
18487
18488             long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
18489             long now = SystemClock.uptimeMillis();
18490             if (when < (now+GC_TIMEOUT)) {
18491                 when = now + GC_TIMEOUT;
18492             }
18493             mHandler.sendMessageAtTime(msg, when);
18494         }
18495     }
18496
18497     /**
18498      * Add a process to the array of processes waiting to be GCed.  Keeps the
18499      * list in sorted order by the last GC time.  The process can't already be
18500      * on the list.
18501      */
18502     final void addProcessToGcListLocked(ProcessRecord proc) {
18503         boolean added = false;
18504         for (int i=mProcessesToGc.size()-1; i>=0; i--) {
18505             if (mProcessesToGc.get(i).lastRequestedGc <
18506                     proc.lastRequestedGc) {
18507                 added = true;
18508                 mProcessesToGc.add(i+1, proc);
18509                 break;
18510             }
18511         }
18512         if (!added) {
18513             mProcessesToGc.add(0, proc);
18514         }
18515     }
18516
18517     /**
18518      * Set up to ask a process to GC itself.  This will either do it
18519      * immediately, or put it on the list of processes to gc the next
18520      * time things are idle.
18521      */
18522     final void scheduleAppGcLocked(ProcessRecord app) {
18523         long now = SystemClock.uptimeMillis();
18524         if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
18525             return;
18526         }
18527         if (!mProcessesToGc.contains(app)) {
18528             addProcessToGcListLocked(app);
18529             scheduleAppGcsLocked();
18530         }
18531     }
18532
18533     final void checkExcessivePowerUsageLocked(boolean doKills) {
18534         updateCpuStatsNow();
18535
18536         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
18537         boolean doWakeKills = doKills;
18538         boolean doCpuKills = doKills;
18539         if (mLastPowerCheckRealtime == 0) {
18540             doWakeKills = false;
18541         }
18542         if (mLastPowerCheckUptime == 0) {
18543             doCpuKills = false;
18544         }
18545         if (stats.isScreenOn()) {
18546             doWakeKills = false;
18547         }
18548         final long curRealtime = SystemClock.elapsedRealtime();
18549         final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
18550         final long curUptime = SystemClock.uptimeMillis();
18551         final long uptimeSince = curUptime - mLastPowerCheckUptime;
18552         mLastPowerCheckRealtime = curRealtime;
18553         mLastPowerCheckUptime = curUptime;
18554         if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
18555             doWakeKills = false;
18556         }
18557         if (uptimeSince < CPU_MIN_CHECK_DURATION) {
18558             doCpuKills = false;
18559         }
18560         int i = mLruProcesses.size();
18561         while (i > 0) {
18562             i--;
18563             ProcessRecord app = mLruProcesses.get(i);
18564             if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
18565                 long wtime;
18566                 synchronized (stats) {
18567                     wtime = stats.getProcessWakeTime(app.info.uid,
18568                             app.pid, curRealtime);
18569                 }
18570                 long wtimeUsed = wtime - app.lastWakeTime;
18571                 long cputimeUsed = app.curCpuTime - app.lastCpuTime;
18572                 if (DEBUG_POWER) {
18573                     StringBuilder sb = new StringBuilder(128);
18574                     sb.append("Wake for ");
18575                     app.toShortString(sb);
18576                     sb.append(": over ");
18577                     TimeUtils.formatDuration(realtimeSince, sb);
18578                     sb.append(" used ");
18579                     TimeUtils.formatDuration(wtimeUsed, sb);
18580                     sb.append(" (");
18581                     sb.append((wtimeUsed*100)/realtimeSince);
18582                     sb.append("%)");
18583                     Slog.i(TAG_POWER, sb.toString());
18584                     sb.setLength(0);
18585                     sb.append("CPU for ");
18586                     app.toShortString(sb);
18587                     sb.append(": over ");
18588                     TimeUtils.formatDuration(uptimeSince, sb);
18589                     sb.append(" used ");
18590                     TimeUtils.formatDuration(cputimeUsed, sb);
18591                     sb.append(" (");
18592                     sb.append((cputimeUsed*100)/uptimeSince);
18593                     sb.append("%)");
18594                     Slog.i(TAG_POWER, sb.toString());
18595                 }
18596                 // If a process has held a wake lock for more
18597                 // than 50% of the time during this period,
18598                 // that sounds bad.  Kill!
18599                 if (doWakeKills && realtimeSince > 0
18600                         && ((wtimeUsed*100)/realtimeSince) >= 50) {
18601                     synchronized (stats) {
18602                         stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
18603                                 realtimeSince, wtimeUsed);
18604                     }
18605                     app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
18606                     app.baseProcessTracker.reportExcessiveWake(app.pkgList);
18607                 } else if (doCpuKills && uptimeSince > 0
18608                         && ((cputimeUsed*100)/uptimeSince) >= 25) {
18609                     synchronized (stats) {
18610                         stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
18611                                 uptimeSince, cputimeUsed);
18612                     }
18613                     app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
18614                     app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
18615                 } else {
18616                     app.lastWakeTime = wtime;
18617                     app.lastCpuTime = app.curCpuTime;
18618                 }
18619             }
18620         }
18621     }
18622
18623     private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now) {
18624         boolean success = true;
18625
18626         if (app.curRawAdj != app.setRawAdj) {
18627             app.setRawAdj = app.curRawAdj;
18628         }
18629
18630         int changes = 0;
18631
18632         if (app.curAdj != app.setAdj) {
18633             ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
18634             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
18635                     "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
18636                     + app.adjType);
18637             app.setAdj = app.curAdj;
18638         }
18639
18640         if (app.setSchedGroup != app.curSchedGroup) {
18641             app.setSchedGroup = app.curSchedGroup;
18642             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
18643                     "Setting process group of " + app.processName
18644                     + " to " + app.curSchedGroup);
18645             if (app.waitingToKill != null && app.curReceiver == null
18646                     && app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
18647                 app.kill(app.waitingToKill, true);
18648                 success = false;
18649             } else {
18650                 if (true) {
18651                     long oldId = Binder.clearCallingIdentity();
18652                     try {
18653                         Process.setProcessGroup(app.pid, app.curSchedGroup);
18654                     } catch (Exception e) {
18655                         Slog.w(TAG, "Failed setting process group of " + app.pid
18656                                 + " to " + app.curSchedGroup);
18657                         e.printStackTrace();
18658                     } finally {
18659                         Binder.restoreCallingIdentity(oldId);
18660                     }
18661                 } else {
18662                     if (app.thread != null) {
18663                         try {
18664                             app.thread.setSchedulingGroup(app.curSchedGroup);
18665                         } catch (RemoteException e) {
18666                         }
18667                     }
18668                 }
18669                 Process.setSwappiness(app.pid,
18670                         app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
18671             }
18672         }
18673         if (app.repForegroundActivities != app.foregroundActivities) {
18674             app.repForegroundActivities = app.foregroundActivities;
18675             changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
18676         }
18677         if (app.repProcState != app.curProcState) {
18678             app.repProcState = app.curProcState;
18679             changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
18680             if (app.thread != null) {
18681                 try {
18682                     if (false) {
18683                         //RuntimeException h = new RuntimeException("here");
18684                         Slog.i(TAG, "Sending new process state " + app.repProcState
18685                                 + " to " + app /*, h*/);
18686                     }
18687                     app.thread.setProcessState(app.repProcState);
18688                 } catch (RemoteException e) {
18689                 }
18690             }
18691         }
18692         if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
18693                 || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
18694             if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
18695                 // Experimental code to more aggressively collect pss while
18696                 // running test...  the problem is that this tends to collect
18697                 // the data right when a process is transitioning between process
18698                 // states, which well tend to give noisy data.
18699                 long start = SystemClock.uptimeMillis();
18700                 long pss = Debug.getPss(app.pid, mTmpLong, null);
18701                 recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], now);
18702                 mPendingPssProcesses.remove(app);
18703                 Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
18704                         + " to " + app.curProcState + ": "
18705                         + (SystemClock.uptimeMillis()-start) + "ms");
18706             }
18707             app.lastStateTime = now;
18708             app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
18709                     mTestPssMode, isSleeping(), now);
18710             if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
18711                     + ProcessList.makeProcStateString(app.setProcState) + " to "
18712                     + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
18713                     + (app.nextPssTime-now) + ": " + app);
18714         } else {
18715             if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
18716                     && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
18717                     mTestPssMode)))) {
18718                 requestPssLocked(app, app.setProcState);
18719                 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
18720                         mTestPssMode, isSleeping(), now);
18721             } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
18722                     "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
18723         }
18724         if (app.setProcState != app.curProcState) {
18725             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
18726                     "Proc state change of " + app.processName
18727                     + " to " + app.curProcState);
18728             boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
18729             boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
18730             if (setImportant && !curImportant) {
18731                 // This app is no longer something we consider important enough to allow to
18732                 // use arbitrary amounts of battery power.  Note
18733                 // its current wake lock time to later know to kill it if
18734                 // it is not behaving well.
18735                 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
18736                 synchronized (stats) {
18737                     app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
18738                             app.pid, SystemClock.elapsedRealtime());
18739                 }
18740                 app.lastCpuTime = app.curCpuTime;
18741
18742             }
18743             // Inform UsageStats of important process state change
18744             // Must be called before updating setProcState
18745             maybeUpdateUsageStatsLocked(app);
18746
18747             app.setProcState = app.curProcState;
18748             if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
18749                 app.notCachedSinceIdle = false;
18750             }
18751             if (!doingAll) {
18752                 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
18753             } else {
18754                 app.procStateChanged = true;
18755             }
18756         }
18757
18758         if (changes != 0) {
18759             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18760                     "Changes in " + app + ": " + changes);
18761             int i = mPendingProcessChanges.size()-1;
18762             ProcessChangeItem item = null;
18763             while (i >= 0) {
18764                 item = mPendingProcessChanges.get(i);
18765                 if (item.pid == app.pid) {
18766                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18767                             "Re-using existing item: " + item);
18768                     break;
18769                 }
18770                 i--;
18771             }
18772             if (i < 0) {
18773                 // No existing item in pending changes; need a new one.
18774                 final int NA = mAvailProcessChanges.size();
18775                 if (NA > 0) {
18776                     item = mAvailProcessChanges.remove(NA-1);
18777                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18778                             "Retrieving available item: " + item);
18779                 } else {
18780                     item = new ProcessChangeItem();
18781                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18782                             "Allocating new item: " + item);
18783                 }
18784                 item.changes = 0;
18785                 item.pid = app.pid;
18786                 item.uid = app.info.uid;
18787                 if (mPendingProcessChanges.size() == 0) {
18788                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18789                             "*** Enqueueing dispatch processes changed!");
18790                     mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
18791                 }
18792                 mPendingProcessChanges.add(item);
18793             }
18794             item.changes |= changes;
18795             item.processState = app.repProcState;
18796             item.foregroundActivities = app.repForegroundActivities;
18797             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18798                     "Item " + Integer.toHexString(System.identityHashCode(item))
18799                     + " " + app.toShortString() + ": changes=" + item.changes
18800                     + " procState=" + item.processState
18801                     + " foreground=" + item.foregroundActivities
18802                     + " type=" + app.adjType + " source=" + app.adjSource
18803                     + " target=" + app.adjTarget);
18804         }
18805
18806         return success;
18807     }
18808
18809     private final void enqueueUidChangeLocked(UidRecord uidRec, boolean gone) {
18810         if (uidRec.pendingChange == null) {
18811             if (mPendingUidChanges.size() == 0) {
18812                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
18813                         "*** Enqueueing dispatch uid changed!");
18814                 mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_MSG).sendToTarget();
18815             }
18816             final int NA = mAvailUidChanges.size();
18817             if (NA > 0) {
18818                 uidRec.pendingChange = mAvailUidChanges.remove(NA-1);
18819                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
18820                         "Retrieving available item: " + uidRec.pendingChange);
18821             } else {
18822                 uidRec.pendingChange = new UidRecord.ChangeItem();
18823                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
18824                         "Allocating new item: " + uidRec.pendingChange);
18825             }
18826             uidRec.pendingChange.uidRecord = uidRec;
18827             uidRec.pendingChange.uid = uidRec.uid;
18828             mPendingUidChanges.add(uidRec.pendingChange);
18829         }
18830         uidRec.pendingChange.gone = gone;
18831         uidRec.pendingChange.processState = uidRec.setProcState;
18832     }
18833
18834     private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
18835             String authority) {
18836         if (app == null) return;
18837         if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
18838             UserState userState = mStartedUsers.get(app.userId);
18839             if (userState == null) return;
18840             final long now = SystemClock.elapsedRealtime();
18841             Long lastReported = userState.mProviderLastReportedFg.get(authority);
18842             if (lastReported == null || lastReported < now - 60 * 1000L) {
18843                 mUsageStatsService.reportContentProviderUsage(
18844                         authority, providerPkgName, app.userId);
18845                 userState.mProviderLastReportedFg.put(authority, now);
18846             }
18847         }
18848     }
18849
18850     private void maybeUpdateUsageStatsLocked(ProcessRecord app) {
18851         if (DEBUG_USAGE_STATS) {
18852             Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
18853                     + "] state changes: old = " + app.setProcState + ", new = "
18854                     + app.curProcState);
18855         }
18856         if (mUsageStatsService == null) {
18857             return;
18858         }
18859         boolean isInteraction;
18860         // To avoid some abuse patterns, we are going to be careful about what we consider
18861         // to be an app interaction.  Being the top activity doesn't count while the display
18862         // is sleeping, nor do short foreground services.
18863         if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
18864             isInteraction = true;
18865             app.fgInteractionTime = 0;
18866         } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
18867             final long now = SystemClock.elapsedRealtime();
18868             if (app.fgInteractionTime == 0) {
18869                 app.fgInteractionTime = now;
18870                 isInteraction = false;
18871             } else {
18872                 isInteraction = now > app.fgInteractionTime + SERVICE_USAGE_INTERACTION_TIME;
18873             }
18874         } else {
18875             isInteraction = app.curProcState
18876                     <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18877             app.fgInteractionTime = 0;
18878         }
18879         if (isInteraction && !app.reportedInteraction) {
18880             String[] packages = app.getPackageList();
18881             if (packages != null) {
18882                 for (int i = 0; i < packages.length; i++) {
18883                     mUsageStatsService.reportEvent(packages[i], app.userId,
18884                             UsageEvents.Event.SYSTEM_INTERACTION);
18885                 }
18886             }
18887         }
18888         app.reportedInteraction = isInteraction;
18889     }
18890
18891     private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
18892         if (proc.thread != null) {
18893             if (proc.baseProcessTracker != null) {
18894                 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
18895             }
18896             if (proc.repProcState >= 0) {
18897                 mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
18898                         proc.repProcState);
18899             }
18900         }
18901     }
18902
18903     private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
18904             ProcessRecord TOP_APP, boolean doingAll, long now) {
18905         if (app.thread == null) {
18906             return false;
18907         }
18908
18909         computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
18910
18911         return applyOomAdjLocked(app, doingAll, now);
18912     }
18913
18914     final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
18915             boolean oomAdj) {
18916         if (isForeground != proc.foregroundServices) {
18917             proc.foregroundServices = isForeground;
18918             ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
18919                     proc.info.uid);
18920             if (isForeground) {
18921                 if (curProcs == null) {
18922                     curProcs = new ArrayList<ProcessRecord>();
18923                     mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
18924                 }
18925                 if (!curProcs.contains(proc)) {
18926                     curProcs.add(proc);
18927                     mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
18928                             proc.info.packageName, proc.info.uid);
18929                 }
18930             } else {
18931                 if (curProcs != null) {
18932                     if (curProcs.remove(proc)) {
18933                         mBatteryStatsService.noteEvent(
18934                                 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
18935                                 proc.info.packageName, proc.info.uid);
18936                         if (curProcs.size() <= 0) {
18937                             mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
18938                         }
18939                     }
18940                 }
18941             }
18942             if (oomAdj) {
18943                 updateOomAdjLocked();
18944             }
18945         }
18946     }
18947
18948     private final ActivityRecord resumedAppLocked() {
18949         ActivityRecord act = mStackSupervisor.resumedAppLocked();
18950         String pkg;
18951         int uid;
18952         if (act != null) {
18953             pkg = act.packageName;
18954             uid = act.info.applicationInfo.uid;
18955         } else {
18956             pkg = null;
18957             uid = -1;
18958         }
18959         // Has the UID or resumed package name changed?
18960         if (uid != mCurResumedUid || (pkg != mCurResumedPackage
18961                 && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
18962             if (mCurResumedPackage != null) {
18963                 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
18964                         mCurResumedPackage, mCurResumedUid);
18965             }
18966             mCurResumedPackage = pkg;
18967             mCurResumedUid = uid;
18968             if (mCurResumedPackage != null) {
18969                 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
18970                         mCurResumedPackage, mCurResumedUid);
18971             }
18972         }
18973         return act;
18974     }
18975
18976     final boolean updateOomAdjLocked(ProcessRecord app) {
18977         final ActivityRecord TOP_ACT = resumedAppLocked();
18978         final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
18979         final boolean wasCached = app.cached;
18980
18981         mAdjSeq++;
18982
18983         // This is the desired cached adjusment we want to tell it to use.
18984         // If our app is currently cached, we know it, and that is it.  Otherwise,
18985         // we don't know it yet, and it needs to now be cached we will then
18986         // need to do a complete oom adj.
18987         final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
18988                 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
18989         boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
18990                 SystemClock.uptimeMillis());
18991         if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
18992             // Changed to/from cached state, so apps after it in the LRU
18993             // list may also be changed.
18994             updateOomAdjLocked();
18995         }
18996         return success;
18997     }
18998
18999     final void updateOomAdjLocked() {
19000         final ActivityRecord TOP_ACT = resumedAppLocked();
19001         final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
19002         final long now = SystemClock.uptimeMillis();
19003         final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
19004         final int N = mLruProcesses.size();
19005
19006         if (false) {
19007             RuntimeException e = new RuntimeException();
19008             e.fillInStackTrace();
19009             Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
19010         }
19011
19012         // Reset state in all uid records.
19013         for (int i=mActiveUids.size()-1; i>=0; i--) {
19014             final UidRecord uidRec = mActiveUids.valueAt(i);
19015             if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19016                     "Starting update of " + uidRec);
19017             uidRec.reset();
19018         }
19019
19020         mAdjSeq++;
19021         mNewNumServiceProcs = 0;
19022         mNewNumAServiceProcs = 0;
19023
19024         final int emptyProcessLimit;
19025         final int cachedProcessLimit;
19026         if (mProcessLimit <= 0) {
19027             emptyProcessLimit = cachedProcessLimit = 0;
19028         } else if (mProcessLimit == 1) {
19029             emptyProcessLimit = 1;
19030             cachedProcessLimit = 0;
19031         } else {
19032             emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
19033             cachedProcessLimit = mProcessLimit - emptyProcessLimit;
19034         }
19035
19036         // Let's determine how many processes we have running vs.
19037         // how many slots we have for background processes; we may want
19038         // to put multiple processes in a slot of there are enough of
19039         // them.
19040         int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
19041                 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
19042         int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
19043         if (numEmptyProcs > cachedProcessLimit) {
19044             // If there are more empty processes than our limit on cached
19045             // processes, then use the cached process limit for the factor.
19046             // This ensures that the really old empty processes get pushed
19047             // down to the bottom, so if we are running low on memory we will
19048             // have a better chance at keeping around more cached processes
19049             // instead of a gazillion empty processes.
19050             numEmptyProcs = cachedProcessLimit;
19051         }
19052         int emptyFactor = numEmptyProcs/numSlots;
19053         if (emptyFactor < 1) emptyFactor = 1;
19054         int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
19055         if (cachedFactor < 1) cachedFactor = 1;
19056         int stepCached = 0;
19057         int stepEmpty = 0;
19058         int numCached = 0;
19059         int numEmpty = 0;
19060         int numTrimming = 0;
19061
19062         mNumNonCachedProcs = 0;
19063         mNumCachedHiddenProcs = 0;
19064
19065         // First update the OOM adjustment for each of the
19066         // application processes based on their current state.
19067         int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
19068         int nextCachedAdj = curCachedAdj+1;
19069         int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
19070         int nextEmptyAdj = curEmptyAdj+2;
19071         for (int i=N-1; i>=0; i--) {
19072             ProcessRecord app = mLruProcesses.get(i);
19073             if (!app.killedByAm && app.thread != null) {
19074                 app.procStateChanged = false;
19075                 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
19076
19077                 // If we haven't yet assigned the final cached adj
19078                 // to the process, do that now.
19079                 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
19080                     switch (app.curProcState) {
19081                         case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
19082                         case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
19083                             // This process is a cached process holding activities...
19084                             // assign it the next cached value for that type, and then
19085                             // step that cached level.
19086                             app.curRawAdj = curCachedAdj;
19087                             app.curAdj = app.modifyRawOomAdj(curCachedAdj);
19088                             if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
19089                                     + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
19090                                     + ")");
19091                             if (curCachedAdj != nextCachedAdj) {
19092                                 stepCached++;
19093                                 if (stepCached >= cachedFactor) {
19094                                     stepCached = 0;
19095                                     curCachedAdj = nextCachedAdj;
19096                                     nextCachedAdj += 2;
19097                                     if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
19098                                         nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
19099                                     }
19100                                 }
19101                             }
19102                             break;
19103                         default:
19104                             // For everything else, assign next empty cached process
19105                             // level and bump that up.  Note that this means that
19106                             // long-running services that have dropped down to the
19107                             // cached level will be treated as empty (since their process
19108                             // state is still as a service), which is what we want.
19109                             app.curRawAdj = curEmptyAdj;
19110                             app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
19111                             if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
19112                                     + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
19113                                     + ")");
19114                             if (curEmptyAdj != nextEmptyAdj) {
19115                                 stepEmpty++;
19116                                 if (stepEmpty >= emptyFactor) {
19117                                     stepEmpty = 0;
19118                                     curEmptyAdj = nextEmptyAdj;
19119                                     nextEmptyAdj += 2;
19120                                     if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
19121                                         nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
19122                                     }
19123                                 }
19124                             }
19125                             break;
19126                     }
19127                 }
19128
19129                 applyOomAdjLocked(app, true, now);
19130
19131                 // Count the number of process types.
19132                 switch (app.curProcState) {
19133                     case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
19134                     case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
19135                         mNumCachedHiddenProcs++;
19136                         numCached++;
19137                         if (numCached > cachedProcessLimit) {
19138                             app.kill("cached #" + numCached, true);
19139                         }
19140                         break;
19141                     case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
19142                         if (numEmpty > ProcessList.TRIM_EMPTY_APPS
19143                                 && app.lastActivityTime < oldTime) {
19144                             app.kill("empty for "
19145                                     + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
19146                                     / 1000) + "s", true);
19147                         } else {
19148                             numEmpty++;
19149                             if (numEmpty > emptyProcessLimit) {
19150                                 app.kill("empty #" + numEmpty, true);
19151                             }
19152                         }
19153                         break;
19154                     default:
19155                         mNumNonCachedProcs++;
19156                         break;
19157                 }
19158
19159                 if (app.isolated && app.services.size() <= 0) {
19160                     // If this is an isolated process, and there are no
19161                     // services running in it, then the process is no longer
19162                     // needed.  We agressively kill these because we can by
19163                     // definition not re-use the same process again, and it is
19164                     // good to avoid having whatever code was running in them
19165                     // left sitting around after no longer needed.
19166                     app.kill("isolated not needed", true);
19167                 } else {
19168                     // Keeping this process, update its uid.
19169                     final UidRecord uidRec = app.uidRecord;
19170                     if (uidRec != null && uidRec.curProcState > app.curProcState) {
19171                         uidRec.curProcState = app.curProcState;
19172                     }
19173                 }
19174
19175                 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
19176                         && !app.killedByAm) {
19177                     numTrimming++;
19178                 }
19179             }
19180         }
19181
19182         mNumServiceProcs = mNewNumServiceProcs;
19183
19184         // Now determine the memory trimming level of background processes.
19185         // Unfortunately we need to start at the back of the list to do this
19186         // properly.  We only do this if the number of background apps we
19187         // are managing to keep around is less than half the maximum we desire;
19188         // if we are keeping a good number around, we'll let them use whatever
19189         // memory they want.
19190         final int numCachedAndEmpty = numCached + numEmpty;
19191         int memFactor;
19192         if (numCached <= ProcessList.TRIM_CACHED_APPS
19193                 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
19194             if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
19195                 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
19196             } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
19197                 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
19198             } else {
19199                 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
19200             }
19201         } else {
19202             memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
19203         }
19204         // We always allow the memory level to go up (better).  We only allow it to go
19205         // down if we are in a state where that is allowed, *and* the total number of processes
19206         // has gone down since last time.
19207         if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
19208                 + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
19209                 + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
19210         if (memFactor > mLastMemoryLevel) {
19211             if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
19212                 memFactor = mLastMemoryLevel;
19213                 if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
19214             }
19215         }
19216         mLastMemoryLevel = memFactor;
19217         mLastNumProcesses = mLruProcesses.size();
19218         boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
19219         final int trackerMemFactor = mProcessStats.getMemFactorLocked();
19220         if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
19221             if (mLowRamStartTime == 0) {
19222                 mLowRamStartTime = now;
19223             }
19224             int step = 0;
19225             int fgTrimLevel;
19226             switch (memFactor) {
19227                 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
19228                     fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
19229                     break;
19230                 case ProcessStats.ADJ_MEM_FACTOR_LOW:
19231                     fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
19232                     break;
19233                 default:
19234                     fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
19235                     break;
19236             }
19237             int factor = numTrimming/3;
19238             int minFactor = 2;
19239             if (mHomeProcess != null) minFactor++;
19240             if (mPreviousProcess != null) minFactor++;
19241             if (factor < minFactor) factor = minFactor;
19242             int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
19243             for (int i=N-1; i>=0; i--) {
19244                 ProcessRecord app = mLruProcesses.get(i);
19245                 if (allChanged || app.procStateChanged) {
19246                     setProcessTrackerStateLocked(app, trackerMemFactor, now);
19247                     app.procStateChanged = false;
19248                 }
19249                 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
19250                         && !app.killedByAm) {
19251                     if (app.trimMemoryLevel < curLevel && app.thread != null) {
19252                         try {
19253                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19254                                     "Trimming memory of " + app.processName + " to " + curLevel);
19255                             app.thread.scheduleTrimMemory(curLevel);
19256                         } catch (RemoteException e) {
19257                         }
19258                         if (false) {
19259                             // For now we won't do this; our memory trimming seems
19260                             // to be good enough at this point that destroying
19261                             // activities causes more harm than good.
19262                             if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
19263                                     && app != mHomeProcess && app != mPreviousProcess) {
19264                                 // Need to do this on its own message because the stack may not
19265                                 // be in a consistent state at this point.
19266                                 // For these apps we will also finish their activities
19267                                 // to help them free memory.
19268                                 mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
19269                             }
19270                         }
19271                     }
19272                     app.trimMemoryLevel = curLevel;
19273                     step++;
19274                     if (step >= factor) {
19275                         step = 0;
19276                         switch (curLevel) {
19277                             case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
19278                                 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
19279                                 break;
19280                             case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
19281                                 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
19282                                 break;
19283                         }
19284                     }
19285                 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
19286                     if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
19287                             && app.thread != null) {
19288                         try {
19289                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19290                                     "Trimming memory of heavy-weight " + app.processName
19291                                     + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
19292                             app.thread.scheduleTrimMemory(
19293                                     ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
19294                         } catch (RemoteException e) {
19295                         }
19296                     }
19297                     app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
19298                 } else {
19299                     if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
19300                             || app.systemNoUi) && app.pendingUiClean) {
19301                         // If this application is now in the background and it
19302                         // had done UI, then give it the special trim level to
19303                         // have it free UI resources.
19304                         final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
19305                         if (app.trimMemoryLevel < level && app.thread != null) {
19306                             try {
19307                                 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19308                                         "Trimming memory of bg-ui " + app.processName
19309                                         + " to " + level);
19310                                 app.thread.scheduleTrimMemory(level);
19311                             } catch (RemoteException e) {
19312                             }
19313                         }
19314                         app.pendingUiClean = false;
19315                     }
19316                     if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
19317                         try {
19318                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19319                                     "Trimming memory of fg " + app.processName
19320                                     + " to " + fgTrimLevel);
19321                             app.thread.scheduleTrimMemory(fgTrimLevel);
19322                         } catch (RemoteException e) {
19323                         }
19324                     }
19325                     app.trimMemoryLevel = fgTrimLevel;
19326                 }
19327             }
19328         } else {
19329             if (mLowRamStartTime != 0) {
19330                 mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
19331                 mLowRamStartTime = 0;
19332             }
19333             for (int i=N-1; i>=0; i--) {
19334                 ProcessRecord app = mLruProcesses.get(i);
19335                 if (allChanged || app.procStateChanged) {
19336                     setProcessTrackerStateLocked(app, trackerMemFactor, now);
19337                     app.procStateChanged = false;
19338                 }
19339                 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
19340                         || app.systemNoUi) && app.pendingUiClean) {
19341                     if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
19342                             && app.thread != null) {
19343                         try {
19344                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19345                                     "Trimming memory of ui hidden " + app.processName
19346                                     + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
19347                             app.thread.scheduleTrimMemory(
19348                                     ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
19349                         } catch (RemoteException e) {
19350                         }
19351                     }
19352                     app.pendingUiClean = false;
19353                 }
19354                 app.trimMemoryLevel = 0;
19355             }
19356         }
19357
19358         if (mAlwaysFinishActivities) {
19359             // Need to do this on its own message because the stack may not
19360             // be in a consistent state at this point.
19361             mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
19362         }
19363
19364         if (allChanged) {
19365             requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
19366         }
19367
19368         // Update from any uid changes.
19369         for (int i=mActiveUids.size()-1; i>=0; i--) {
19370             final UidRecord uidRec = mActiveUids.valueAt(i);
19371             if (uidRec.setProcState != uidRec.curProcState) {
19372                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19373                         "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
19374                         + " to " + uidRec.curProcState);
19375                 uidRec.setProcState = uidRec.curProcState;
19376                 enqueueUidChangeLocked(uidRec, false);
19377             }
19378         }
19379
19380         if (mProcessStats.shouldWriteNowLocked(now)) {
19381             mHandler.post(new Runnable() {
19382                 @Override public void run() {
19383                     synchronized (ActivityManagerService.this) {
19384                         mProcessStats.writeStateAsyncLocked();
19385                     }
19386                 }
19387             });
19388         }
19389
19390         if (DEBUG_OOM_ADJ) {
19391             final long duration = SystemClock.uptimeMillis() - now;
19392             if (false) {
19393                 Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
19394                         new RuntimeException("here").fillInStackTrace());
19395             } else {
19396                 Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
19397             }
19398         }
19399     }
19400
19401     final void trimApplications() {
19402         synchronized (this) {
19403             int i;
19404
19405             // First remove any unused application processes whose package
19406             // has been removed.
19407             for (i=mRemovedProcesses.size()-1; i>=0; i--) {
19408                 final ProcessRecord app = mRemovedProcesses.get(i);
19409                 if (app.activities.size() == 0
19410                         && app.curReceiver == null && app.services.size() == 0) {
19411                     Slog.i(
19412                         TAG, "Exiting empty application process "
19413                         + app.processName + " ("
19414                         + (app.thread != null ? app.thread.asBinder() : null)
19415                         + ")\n");
19416                     if (app.pid > 0 && app.pid != MY_PID) {
19417                         app.kill("empty", false);
19418                     } else {
19419                         try {
19420                             app.thread.scheduleExit();
19421                         } catch (Exception e) {
19422                             // Ignore exceptions.
19423                         }
19424                     }
19425                     cleanUpApplicationRecordLocked(app, false, true, -1);
19426                     mRemovedProcesses.remove(i);
19427
19428                     if (app.persistent) {
19429                         addAppLocked(app.info, false, null /* ABI override */);
19430                     }
19431                 }
19432             }
19433
19434             // Now update the oom adj for all processes.
19435             updateOomAdjLocked();
19436         }
19437     }
19438
19439     /** This method sends the specified signal to each of the persistent apps */
19440     public void signalPersistentProcesses(int sig) throws RemoteException {
19441         if (sig != Process.SIGNAL_USR1) {
19442             throw new SecurityException("Only SIGNAL_USR1 is allowed");
19443         }
19444
19445         synchronized (this) {
19446             if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
19447                     != PackageManager.PERMISSION_GRANTED) {
19448                 throw new SecurityException("Requires permission "
19449                         + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
19450             }
19451
19452             for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
19453                 ProcessRecord r = mLruProcesses.get(i);
19454                 if (r.thread != null && r.persistent) {
19455                     Process.sendSignal(r.pid, sig);
19456                 }
19457             }
19458         }
19459     }
19460
19461     private void stopProfilerLocked(ProcessRecord proc, int profileType) {
19462         if (proc == null || proc == mProfileProc) {
19463             proc = mProfileProc;
19464             profileType = mProfileType;
19465             clearProfilerLocked();
19466         }
19467         if (proc == null) {
19468             return;
19469         }
19470         try {
19471             proc.thread.profilerControl(false, null, profileType);
19472         } catch (RemoteException e) {
19473             throw new IllegalStateException("Process disappeared");
19474         }
19475     }
19476
19477     private void clearProfilerLocked() {
19478         if (mProfileFd != null) {
19479             try {
19480                 mProfileFd.close();
19481             } catch (IOException e) {
19482             }
19483         }
19484         mProfileApp = null;
19485         mProfileProc = null;
19486         mProfileFile = null;
19487         mProfileType = 0;
19488         mAutoStopProfiler = false;
19489         mSamplingInterval = 0;
19490     }
19491
19492     public boolean profileControl(String process, int userId, boolean start,
19493             ProfilerInfo profilerInfo, int profileType) throws RemoteException {
19494
19495         try {
19496             synchronized (this) {
19497                 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
19498                 // its own permission.
19499                 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
19500                         != PackageManager.PERMISSION_GRANTED) {
19501                     throw new SecurityException("Requires permission "
19502                             + android.Manifest.permission.SET_ACTIVITY_WATCHER);
19503                 }
19504
19505                 if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
19506                     throw new IllegalArgumentException("null profile info or fd");
19507                 }
19508
19509                 ProcessRecord proc = null;
19510                 if (process != null) {
19511                     proc = findProcessLocked(process, userId, "profileControl");
19512                 }
19513
19514                 if (start && (proc == null || proc.thread == null)) {
19515                     throw new IllegalArgumentException("Unknown process: " + process);
19516                 }
19517
19518                 if (start) {
19519                     stopProfilerLocked(null, 0);
19520                     setProfileApp(proc.info, proc.processName, profilerInfo);
19521                     mProfileProc = proc;
19522                     mProfileType = profileType;
19523                     ParcelFileDescriptor fd = profilerInfo.profileFd;
19524                     try {
19525                         fd = fd.dup();
19526                     } catch (IOException e) {
19527                         fd = null;
19528                     }
19529                     profilerInfo.profileFd = fd;
19530                     proc.thread.profilerControl(start, profilerInfo, profileType);
19531                     fd = null;
19532                     mProfileFd = null;
19533                 } else {
19534                     stopProfilerLocked(proc, profileType);
19535                     if (profilerInfo != null && profilerInfo.profileFd != null) {
19536                         try {
19537                             profilerInfo.profileFd.close();
19538                         } catch (IOException e) {
19539                         }
19540                     }
19541                 }
19542
19543                 return true;
19544             }
19545         } catch (RemoteException e) {
19546             throw new IllegalStateException("Process disappeared");
19547         } finally {
19548             if (profilerInfo != null && profilerInfo.profileFd != null) {
19549                 try {
19550                     profilerInfo.profileFd.close();
19551                 } catch (IOException e) {
19552                 }
19553             }
19554         }
19555     }
19556
19557     private ProcessRecord findProcessLocked(String process, int userId, String callName) {
19558         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
19559                 userId, true, ALLOW_FULL_ONLY, callName, null);
19560         ProcessRecord proc = null;
19561         try {
19562             int pid = Integer.parseInt(process);
19563             synchronized (mPidsSelfLocked) {
19564                 proc = mPidsSelfLocked.get(pid);
19565             }
19566         } catch (NumberFormatException e) {
19567         }
19568
19569         if (proc == null) {
19570             ArrayMap<String, SparseArray<ProcessRecord>> all
19571                     = mProcessNames.getMap();
19572             SparseArray<ProcessRecord> procs = all.get(process);
19573             if (procs != null && procs.size() > 0) {
19574                 proc = procs.valueAt(0);
19575                 if (userId != UserHandle.USER_ALL && proc.userId != userId) {
19576                     for (int i=1; i<procs.size(); i++) {
19577                         ProcessRecord thisProc = procs.valueAt(i);
19578                         if (thisProc.userId == userId) {
19579                             proc = thisProc;
19580                             break;
19581                         }
19582                     }
19583                 }
19584             }
19585         }
19586
19587         return proc;
19588     }
19589
19590     public boolean dumpHeap(String process, int userId, boolean managed,
19591             String path, ParcelFileDescriptor fd) throws RemoteException {
19592
19593         try {
19594             synchronized (this) {
19595                 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
19596                 // its own permission (same as profileControl).
19597                 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
19598                         != PackageManager.PERMISSION_GRANTED) {
19599                     throw new SecurityException("Requires permission "
19600                             + android.Manifest.permission.SET_ACTIVITY_WATCHER);
19601                 }
19602
19603                 if (fd == null) {
19604                     throw new IllegalArgumentException("null fd");
19605                 }
19606
19607                 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
19608                 if (proc == null || proc.thread == null) {
19609                     throw new IllegalArgumentException("Unknown process: " + process);
19610                 }
19611
19612                 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
19613                 if (!isDebuggable) {
19614                     if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
19615                         throw new SecurityException("Process not debuggable: " + proc);
19616                     }
19617                 }
19618
19619                 proc.thread.dumpHeap(managed, path, fd);
19620                 fd = null;
19621                 return true;
19622             }
19623         } catch (RemoteException e) {
19624             throw new IllegalStateException("Process disappeared");
19625         } finally {
19626             if (fd != null) {
19627                 try {
19628                     fd.close();
19629                 } catch (IOException e) {
19630                 }
19631             }
19632         }
19633     }
19634
19635     @Override
19636     public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
19637             String reportPackage) {
19638         if (processName != null) {
19639             enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
19640                     "setDumpHeapDebugLimit()");
19641         } else {
19642             synchronized (mPidsSelfLocked) {
19643                 ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
19644                 if (proc == null) {
19645                     throw new SecurityException("No process found for calling pid "
19646                             + Binder.getCallingPid());
19647                 }
19648                 if (!Build.IS_DEBUGGABLE
19649                         && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
19650                     throw new SecurityException("Not running a debuggable build");
19651                 }
19652                 processName = proc.processName;
19653                 uid = proc.uid;
19654                 if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
19655                     throw new SecurityException("Package " + reportPackage + " is not running in "
19656                             + proc);
19657                 }
19658             }
19659         }
19660         synchronized (this) {
19661             if (maxMemSize > 0) {
19662                 mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
19663             } else {
19664                 if (uid != 0) {
19665                     mMemWatchProcesses.remove(processName, uid);
19666                 } else {
19667                     mMemWatchProcesses.getMap().remove(processName);
19668                 }
19669             }
19670         }
19671     }
19672
19673     @Override
19674     public void dumpHeapFinished(String path) {
19675         synchronized (this) {
19676             if (Binder.getCallingPid() != mMemWatchDumpPid) {
19677                 Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
19678                         + " does not match last pid " + mMemWatchDumpPid);
19679                 return;
19680             }
19681             if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
19682                 Slog.w(TAG, "dumpHeapFinished: Calling path " + path
19683                         + " does not match last path " + mMemWatchDumpFile);
19684                 return;
19685             }
19686             if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
19687             mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
19688         }
19689     }
19690
19691     /** In this method we try to acquire our lock to make sure that we have not deadlocked */
19692     public void monitor() {
19693         synchronized (this) { }
19694     }
19695
19696     void onCoreSettingsChange(Bundle settings) {
19697         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
19698             ProcessRecord processRecord = mLruProcesses.get(i);
19699             try {
19700                 if (processRecord.thread != null) {
19701                     processRecord.thread.setCoreSettings(settings);
19702                 }
19703             } catch (RemoteException re) {
19704                 /* ignore */
19705             }
19706         }
19707     }
19708
19709     // Multi-user methods
19710
19711     /**
19712      * Start user, if its not already running, but don't bring it to foreground.
19713      */
19714     @Override
19715     public boolean startUserInBackground(final int userId) {
19716         return startUser(userId, /* foreground */ false);
19717     }
19718
19719     /**
19720      * Start user, if its not already running, and bring it to foreground.
19721      */
19722     boolean startUserInForeground(final int userId, Dialog dlg) {
19723         boolean result = startUser(userId, /* foreground */ true);
19724         dlg.dismiss();
19725         return result;
19726     }
19727
19728     /**
19729      * Refreshes the list of users related to the current user when either a
19730      * user switch happens or when a new related user is started in the
19731      * background.
19732      */
19733     private void updateCurrentProfileIdsLocked() {
19734         final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
19735                 mCurrentUserId, false /* enabledOnly */);
19736         int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
19737         for (int i = 0; i < currentProfileIds.length; i++) {
19738             currentProfileIds[i] = profiles.get(i).id;
19739         }
19740         mCurrentProfileIds = currentProfileIds;
19741
19742         synchronized (mUserProfileGroupIdsSelfLocked) {
19743             mUserProfileGroupIdsSelfLocked.clear();
19744             final List<UserInfo> users = getUserManagerLocked().getUsers(false);
19745             for (int i = 0; i < users.size(); i++) {
19746                 UserInfo user = users.get(i);
19747                 if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
19748                     mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
19749                 }
19750             }
19751         }
19752     }
19753
19754     private Set<Integer> getProfileIdsLocked(int userId) {
19755         Set<Integer> userIds = new HashSet<Integer>();
19756         final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
19757                 userId, false /* enabledOnly */);
19758         for (UserInfo user : profiles) {
19759             userIds.add(Integer.valueOf(user.id));
19760         }
19761         return userIds;
19762     }
19763
19764     @Override
19765     public boolean switchUser(final int userId) {
19766         enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
19767         String userName;
19768         synchronized (this) {
19769             UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
19770             if (userInfo == null) {
19771                 Slog.w(TAG, "No user info for user #" + userId);
19772                 return false;
19773             }
19774             if (userInfo.isManagedProfile()) {
19775                 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
19776                 return false;
19777             }
19778             userName = userInfo.name;
19779             mTargetUserId = userId;
19780         }
19781         mUiHandler.removeMessages(START_USER_SWITCH_MSG);
19782         mUiHandler.sendMessage(mUiHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName));
19783         return true;
19784     }
19785
19786     private void showUserSwitchDialog(int userId, String userName) {
19787         // The dialog will show and then initiate the user switch by calling startUserInForeground
19788         Dialog d = new UserSwitchingDialog(this, mContext, userId, userName,
19789                 true /* above system */);
19790         d.show();
19791     }
19792
19793     private boolean startUser(final int userId, final boolean foreground) {
19794         if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
19795                 != PackageManager.PERMISSION_GRANTED) {
19796             String msg = "Permission Denial: switchUser() from pid="
19797                     + Binder.getCallingPid()
19798                     + ", uid=" + Binder.getCallingUid()
19799                     + " requires " + INTERACT_ACROSS_USERS_FULL;
19800             Slog.w(TAG, msg);
19801             throw new SecurityException(msg);
19802         }
19803
19804         if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
19805
19806         final long ident = Binder.clearCallingIdentity();
19807         try {
19808             synchronized (this) {
19809                 final int oldUserId = mCurrentUserId;
19810                 if (oldUserId == userId) {
19811                     return true;
19812                 }
19813
19814                 mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
19815                         "startUser", false);
19816
19817                 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
19818                 if (userInfo == null) {
19819                     Slog.w(TAG, "No user info for user #" + userId);
19820                     return false;
19821                 }
19822                 if (foreground && userInfo.isManagedProfile()) {
19823                     Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
19824                     return false;
19825                 }
19826
19827                 if (foreground) {
19828                     mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
19829                             R.anim.screen_user_enter);
19830                 }
19831
19832                 boolean needStart = false;
19833
19834                 // If the user we are switching to is not currently started, then
19835                 // we need to start it now.
19836                 if (mStartedUsers.get(userId) == null) {
19837                     mStartedUsers.put(userId, new UserState(new UserHandle(userId), false));
19838                     updateStartedUserArrayLocked();
19839                     needStart = true;
19840                 }
19841
19842                 final Integer userIdInt = Integer.valueOf(userId);
19843                 mUserLru.remove(userIdInt);
19844                 mUserLru.add(userIdInt);
19845
19846                 if (foreground) {
19847                     mCurrentUserId = userId;
19848                     mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up
19849                     updateCurrentProfileIdsLocked();
19850                     mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
19851                     // Once the internal notion of the active user has switched, we lock the device
19852                     // with the option to show the user switcher on the keyguard.
19853                     mWindowManager.lockNow(null);
19854                 } else {
19855                     final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
19856                     updateCurrentProfileIdsLocked();
19857                     mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
19858                     mUserLru.remove(currentUserIdInt);
19859                     mUserLru.add(currentUserIdInt);
19860                 }
19861
19862                 final UserState uss = mStartedUsers.get(userId);
19863
19864                 // Make sure user is in the started state.  If it is currently
19865                 // stopping, we need to knock that off.
19866                 if (uss.mState == UserState.STATE_STOPPING) {
19867                     // If we are stopping, we haven't sent ACTION_SHUTDOWN,
19868                     // so we can just fairly silently bring the user back from
19869                     // the almost-dead.
19870                     uss.mState = UserState.STATE_RUNNING;
19871                     updateStartedUserArrayLocked();
19872                     needStart = true;
19873                 } else if (uss.mState == UserState.STATE_SHUTDOWN) {
19874                     // This means ACTION_SHUTDOWN has been sent, so we will
19875                     // need to treat this as a new boot of the user.
19876                     uss.mState = UserState.STATE_BOOTING;
19877                     updateStartedUserArrayLocked();
19878                     needStart = true;
19879                 }
19880
19881                 if (uss.mState == UserState.STATE_BOOTING) {
19882                     // Booting up a new user, need to tell system services about it.
19883                     // Note that this is on the same handler as scheduling of broadcasts,
19884                     // which is important because it needs to go first.
19885                     mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
19886                 }
19887
19888                 if (foreground) {
19889                     mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
19890                             oldUserId));
19891                     mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
19892                     mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
19893                     mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
19894                             oldUserId, userId, uss));
19895                     mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
19896                             oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
19897                 }
19898
19899                 if (needStart) {
19900                     // Send USER_STARTED broadcast
19901                     Intent intent = new Intent(Intent.ACTION_USER_STARTED);
19902                     intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
19903                             | Intent.FLAG_RECEIVER_FOREGROUND);
19904                     intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
19905                     broadcastIntentLocked(null, null, intent,
19906                             null, null, 0, null, null, null, AppOpsManager.OP_NONE,
19907                             null, false, false, MY_PID, Process.SYSTEM_UID, userId);
19908                 }
19909
19910                 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
19911                     if (userId != UserHandle.USER_OWNER) {
19912                         Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
19913                         intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
19914                         broadcastIntentLocked(null, null, intent, null,
19915                                 new IIntentReceiver.Stub() {
19916                                     public void performReceive(Intent intent, int resultCode,
19917                                             String data, Bundle extras, boolean ordered,
19918                                             boolean sticky, int sendingUser) {
19919                                         onUserInitialized(uss, foreground, oldUserId, userId);
19920                                     }
19921                                 }, 0, null, null, null, AppOpsManager.OP_NONE,
19922                                 null, true, false, MY_PID, Process.SYSTEM_UID, userId);
19923                         uss.initializing = true;
19924                     } else {
19925                         getUserManagerLocked().makeInitialized(userInfo.id);
19926                     }
19927                 }
19928
19929                 if (foreground) {
19930                     if (!uss.initializing) {
19931                         moveUserToForeground(uss, oldUserId, userId);
19932                     }
19933                 } else {
19934                     mStackSupervisor.startBackgroundUserLocked(userId, uss);
19935                 }
19936
19937                 if (needStart) {
19938                     Intent intent = new Intent(Intent.ACTION_USER_STARTING);
19939                     intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19940                     intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
19941                     broadcastIntentLocked(null, null, intent,
19942                             null, new IIntentReceiver.Stub() {
19943                                 @Override
19944                                 public void performReceive(Intent intent, int resultCode,
19945                                         String data, Bundle extras, boolean ordered, boolean sticky,
19946                                         int sendingUser) throws RemoteException {
19947                                 }
19948                             }, 0, null, null,
19949                             new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
19950                             null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
19951                 }
19952             }
19953         } finally {
19954             Binder.restoreCallingIdentity(ident);
19955         }
19956
19957         return true;
19958     }
19959
19960     void dispatchForegroundProfileChanged(int userId) {
19961         final int N = mUserSwitchObservers.beginBroadcast();
19962         for (int i = 0; i < N; i++) {
19963             try {
19964                 mUserSwitchObservers.getBroadcastItem(i).onForegroundProfileSwitch(userId);
19965             } catch (RemoteException e) {
19966                 // Ignore
19967             }
19968         }
19969         mUserSwitchObservers.finishBroadcast();
19970     }
19971
19972     void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
19973         long ident = Binder.clearCallingIdentity();
19974         try {
19975             Intent intent;
19976             if (oldUserId >= 0) {
19977                 // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
19978                 List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
19979                 int count = profiles.size();
19980                 for (int i = 0; i < count; i++) {
19981                     int profileUserId = profiles.get(i).id;
19982                     intent = new Intent(Intent.ACTION_USER_BACKGROUND);
19983                     intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
19984                             | Intent.FLAG_RECEIVER_FOREGROUND);
19985                     intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
19986                     broadcastIntentLocked(null, null, intent,
19987                             null, null, 0, null, null, null, AppOpsManager.OP_NONE,
19988                             null, false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
19989                 }
19990             }
19991             if (newUserId >= 0) {
19992                 // Send USER_FOREGROUND broadcast to all profiles of the incoming user
19993                 List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
19994                 int count = profiles.size();
19995                 for (int i = 0; i < count; i++) {
19996                     int profileUserId = profiles.get(i).id;
19997                     intent = new Intent(Intent.ACTION_USER_FOREGROUND);
19998                     intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
19999                             | Intent.FLAG_RECEIVER_FOREGROUND);
20000                     intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
20001                     broadcastIntentLocked(null, null, intent,
20002                             null, null, 0, null, null, null, AppOpsManager.OP_NONE,
20003                             null, false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
20004                 }
20005                 intent = new Intent(Intent.ACTION_USER_SWITCHED);
20006                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
20007                         | Intent.FLAG_RECEIVER_FOREGROUND);
20008                 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
20009                 broadcastIntentLocked(null, null, intent,
20010                         null, null, 0, null, null,
20011                         new String[] {android.Manifest.permission.MANAGE_USERS},
20012                         AppOpsManager.OP_NONE, null, false, false, MY_PID, Process.SYSTEM_UID,
20013                         UserHandle.USER_ALL);
20014             }
20015         } finally {
20016             Binder.restoreCallingIdentity(ident);
20017         }
20018     }
20019
20020     void dispatchUserSwitch(final UserState uss, final int oldUserId,
20021             final int newUserId) {
20022         final int N = mUserSwitchObservers.beginBroadcast();
20023         if (N > 0) {
20024             final IRemoteCallback callback = new IRemoteCallback.Stub() {
20025                 int mCount = 0;
20026                 @Override
20027                 public void sendResult(Bundle data) throws RemoteException {
20028                     synchronized (ActivityManagerService.this) {
20029                         if (mCurUserSwitchCallback == this) {
20030                             mCount++;
20031                             if (mCount == N) {
20032                                 sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
20033                             }
20034                         }
20035                     }
20036                 }
20037             };
20038             synchronized (this) {
20039                 uss.switching = true;
20040                 mCurUserSwitchCallback = callback;
20041             }
20042             for (int i=0; i<N; i++) {
20043                 try {
20044                     mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
20045                             newUserId, callback);
20046                 } catch (RemoteException e) {
20047                 }
20048             }
20049         } else {
20050             synchronized (this) {
20051                 sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
20052             }
20053         }
20054         mUserSwitchObservers.finishBroadcast();
20055     }
20056
20057     void timeoutUserSwitch(UserState uss, int oldUserId, int newUserId) {
20058         synchronized (this) {
20059             Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
20060             sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
20061         }
20062     }
20063
20064     void sendContinueUserSwitchLocked(UserState uss, int oldUserId, int newUserId) {
20065         mCurUserSwitchCallback = null;
20066         mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
20067         mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
20068                 oldUserId, newUserId, uss));
20069     }
20070
20071     void onUserInitialized(UserState uss, boolean foreground, int oldUserId, int newUserId) {
20072         synchronized (this) {
20073             if (foreground) {
20074                 moveUserToForeground(uss, oldUserId, newUserId);
20075             }
20076         }
20077
20078         completeSwitchAndInitialize(uss, newUserId, true, false);
20079     }
20080
20081     void moveUserToForeground(UserState uss, int oldUserId, int newUserId) {
20082         boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss);
20083         if (homeInFront) {
20084             startHomeActivityLocked(newUserId, "moveUserToFroreground");
20085         } else {
20086             mStackSupervisor.resumeTopActivitiesLocked();
20087         }
20088         EventLogTags.writeAmSwitchUser(newUserId);
20089         getUserManagerLocked().onUserForeground(newUserId);
20090         sendUserSwitchBroadcastsLocked(oldUserId, newUserId);
20091     }
20092
20093     void continueUserSwitch(UserState uss, int oldUserId, int newUserId) {
20094         completeSwitchAndInitialize(uss, newUserId, false, true);
20095     }
20096
20097     void completeSwitchAndInitialize(UserState uss, int newUserId,
20098             boolean clearInitializing, boolean clearSwitching) {
20099         boolean unfrozen = false;
20100         synchronized (this) {
20101             if (clearInitializing) {
20102                 uss.initializing = false;
20103                 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
20104             }
20105             if (clearSwitching) {
20106                 uss.switching = false;
20107             }
20108             if (!uss.switching && !uss.initializing) {
20109                 mWindowManager.stopFreezingScreen();
20110                 unfrozen = true;
20111             }
20112         }
20113         if (unfrozen) {
20114             mHandler.removeMessages(REPORT_USER_SWITCH_COMPLETE_MSG);
20115             mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_COMPLETE_MSG,
20116                     newUserId, 0));
20117         }
20118         stopGuestUserIfBackground();
20119     }
20120
20121     /** Called on handler thread */
20122     void dispatchUserSwitchComplete(int userId) {
20123         final int observerCount = mUserSwitchObservers.beginBroadcast();
20124         for (int i = 0; i < observerCount; i++) {
20125             try {
20126                 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(userId);
20127             } catch (RemoteException e) {
20128             }
20129         }
20130         mUserSwitchObservers.finishBroadcast();
20131     }
20132
20133     /**
20134      * Stops the guest user if it has gone to the background.
20135      */
20136     private void stopGuestUserIfBackground() {
20137         synchronized (this) {
20138             final int num = mUserLru.size();
20139             for (int i = 0; i < num; i++) {
20140                 Integer oldUserId = mUserLru.get(i);
20141                 UserState oldUss = mStartedUsers.get(oldUserId);
20142                 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId
20143                         || oldUss.mState == UserState.STATE_STOPPING
20144                         || oldUss.mState == UserState.STATE_SHUTDOWN) {
20145                     continue;
20146                 }
20147                 UserInfo userInfo = mUserManager.getUserInfo(oldUserId);
20148                 if (userInfo.isGuest()) {
20149                     // This is a user to be stopped.
20150                     stopUserLocked(oldUserId, null);
20151                     break;
20152                 }
20153             }
20154         }
20155     }
20156
20157     void scheduleStartProfilesLocked() {
20158         if (!mHandler.hasMessages(START_PROFILES_MSG)) {
20159             mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
20160                     DateUtils.SECOND_IN_MILLIS);
20161         }
20162     }
20163
20164     void startProfilesLocked() {
20165         if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
20166         List<UserInfo> profiles = getUserManagerLocked().getProfiles(
20167                 mCurrentUserId, false /* enabledOnly */);
20168         List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
20169         for (UserInfo user : profiles) {
20170             if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
20171                     && user.id != mCurrentUserId) {
20172                 toStart.add(user);
20173             }
20174         }
20175         final int n = toStart.size();
20176         int i = 0;
20177         for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
20178             startUserInBackground(toStart.get(i).id);
20179         }
20180         if (i < n) {
20181             Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
20182         }
20183     }
20184
20185     void finishUserBoot(UserState uss) {
20186         synchronized (this) {
20187             if (uss.mState == UserState.STATE_BOOTING
20188                     && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
20189                 uss.mState = UserState.STATE_RUNNING;
20190                 final int userId = uss.mHandle.getIdentifier();
20191                 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
20192                 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
20193                 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
20194                 broadcastIntentLocked(null, null, intent,
20195                         null, null, 0, null, null,
20196                         new String[] {android.Manifest.permission.RECEIVE_BOOT_COMPLETED},
20197                         AppOpsManager.OP_NONE, null, true, false, MY_PID, Process.SYSTEM_UID,
20198                         userId);
20199             }
20200         }
20201     }
20202
20203     void finishUserSwitch(UserState uss) {
20204         synchronized (this) {
20205             finishUserBoot(uss);
20206
20207             startProfilesLocked();
20208
20209             int num = mUserLru.size();
20210             int i = 0;
20211             while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
20212                 Integer oldUserId = mUserLru.get(i);
20213                 UserState oldUss = mStartedUsers.get(oldUserId);
20214                 if (oldUss == null) {
20215                     // Shouldn't happen, but be sane if it does.
20216                     mUserLru.remove(i);
20217                     num--;
20218                     continue;
20219                 }
20220                 if (oldUss.mState == UserState.STATE_STOPPING
20221                         || oldUss.mState == UserState.STATE_SHUTDOWN) {
20222                     // This user is already stopping, doesn't count.
20223                     num--;
20224                     i++;
20225                     continue;
20226                 }
20227                 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
20228                     // Owner and current can't be stopped, but count as running.
20229                     i++;
20230                     continue;
20231                 }
20232                 // This is a user to be stopped.
20233                 stopUserLocked(oldUserId, null);
20234                 num--;
20235                 i++;
20236             }
20237         }
20238     }
20239
20240     @Override
20241     public int stopUser(final int userId, final IStopUserCallback callback) {
20242         if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
20243                 != PackageManager.PERMISSION_GRANTED) {
20244             String msg = "Permission Denial: switchUser() from pid="
20245                     + Binder.getCallingPid()
20246                     + ", uid=" + Binder.getCallingUid()
20247                     + " requires " + INTERACT_ACROSS_USERS_FULL;
20248             Slog.w(TAG, msg);
20249             throw new SecurityException(msg);
20250         }
20251         if (userId < 0 || userId == UserHandle.USER_OWNER) {
20252             throw new IllegalArgumentException("Can't stop primary user " + userId);
20253         }
20254         enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
20255         synchronized (this) {
20256             return stopUserLocked(userId, callback);
20257         }
20258     }
20259
20260     private int stopUserLocked(final int userId, final IStopUserCallback callback) {
20261         if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
20262         if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) {
20263             return ActivityManager.USER_OP_IS_CURRENT;
20264         }
20265
20266         final UserState uss = mStartedUsers.get(userId);
20267         if (uss == null) {
20268             // User is not started, nothing to do...  but we do need to
20269             // callback if requested.
20270             if (callback != null) {
20271                 mHandler.post(new Runnable() {
20272                     @Override
20273                     public void run() {
20274                         try {
20275                             callback.userStopped(userId);
20276                         } catch (RemoteException e) {
20277                         }
20278                     }
20279                 });
20280             }
20281             return ActivityManager.USER_OP_SUCCESS;
20282         }
20283
20284         if (callback != null) {
20285             uss.mStopCallbacks.add(callback);
20286         }
20287
20288         if (uss.mState != UserState.STATE_STOPPING
20289                 && uss.mState != UserState.STATE_SHUTDOWN) {
20290             uss.mState = UserState.STATE_STOPPING;
20291             updateStartedUserArrayLocked();
20292
20293             long ident = Binder.clearCallingIdentity();
20294             try {
20295                 // We are going to broadcast ACTION_USER_STOPPING and then
20296                 // once that is done send a final ACTION_SHUTDOWN and then
20297                 // stop the user.
20298                 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
20299                 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
20300                 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
20301                 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
20302                 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
20303                 // This is the result receiver for the final shutdown broadcast.
20304                 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
20305                     @Override
20306                     public void performReceive(Intent intent, int resultCode, String data,
20307                             Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
20308                         finishUserStop(uss);
20309                     }
20310                 };
20311                 // This is the result receiver for the initial stopping broadcast.
20312                 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
20313                     @Override
20314                     public void performReceive(Intent intent, int resultCode, String data,
20315                             Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
20316                         // On to the next.
20317                         synchronized (ActivityManagerService.this) {
20318                             if (uss.mState != UserState.STATE_STOPPING) {
20319                                 // Whoops, we are being started back up.  Abort, abort!
20320                                 return;
20321                             }
20322                             uss.mState = UserState.STATE_SHUTDOWN;
20323                         }
20324                         mBatteryStatsService.noteEvent(
20325                                 BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
20326                                 Integer.toString(userId), userId);
20327                         mSystemServiceManager.stopUser(userId);
20328                         broadcastIntentLocked(null, null, shutdownIntent,
20329                                 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
20330                                 null, true, false, MY_PID, Process.SYSTEM_UID, userId);
20331                     }
20332                 };
20333                 // Kick things off.
20334                 broadcastIntentLocked(null, null, stoppingIntent,
20335                         null, stoppingReceiver, 0, null, null,
20336                         new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
20337                         null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
20338             } finally {
20339                 Binder.restoreCallingIdentity(ident);
20340             }
20341         }
20342
20343         return ActivityManager.USER_OP_SUCCESS;
20344     }
20345
20346     void finishUserStop(UserState uss) {
20347         final int userId = uss.mHandle.getIdentifier();
20348         boolean stopped;
20349         ArrayList<IStopUserCallback> callbacks;
20350         synchronized (this) {
20351             callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
20352             if (mStartedUsers.get(userId) != uss) {
20353                 stopped = false;
20354             } else if (uss.mState != UserState.STATE_SHUTDOWN) {
20355                 stopped = false;
20356             } else {
20357                 stopped = true;
20358                 // User can no longer run.
20359                 mStartedUsers.remove(userId);
20360                 mUserLru.remove(Integer.valueOf(userId));
20361                 updateStartedUserArrayLocked();
20362
20363                 // Clean up all state and processes associated with the user.
20364                 // Kill all the processes for the user.
20365                 forceStopUserLocked(userId, "finish user");
20366             }
20367
20368             // Explicitly remove the old information in mRecentTasks.
20369             mRecentTasks.removeTasksForUserLocked(userId);
20370         }
20371
20372         for (int i=0; i<callbacks.size(); i++) {
20373             try {
20374                 if (stopped) callbacks.get(i).userStopped(userId);
20375                 else callbacks.get(i).userStopAborted(userId);
20376             } catch (RemoteException e) {
20377             }
20378         }
20379
20380         if (stopped) {
20381             mSystemServiceManager.cleanupUser(userId);
20382             synchronized (this) {
20383                 mStackSupervisor.removeUserLocked(userId);
20384             }
20385         }
20386     }
20387
20388     @Override
20389     public UserInfo getCurrentUser() {
20390         if ((checkCallingPermission(INTERACT_ACROSS_USERS)
20391                 != PackageManager.PERMISSION_GRANTED) && (
20392                 checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
20393                 != PackageManager.PERMISSION_GRANTED)) {
20394             String msg = "Permission Denial: getCurrentUser() from pid="
20395                     + Binder.getCallingPid()
20396                     + ", uid=" + Binder.getCallingUid()
20397                     + " requires " + INTERACT_ACROSS_USERS;
20398             Slog.w(TAG, msg);
20399             throw new SecurityException(msg);
20400         }
20401         synchronized (this) {
20402             int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
20403             return getUserManagerLocked().getUserInfo(userId);
20404         }
20405     }
20406
20407     int getCurrentUserIdLocked() {
20408         return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
20409     }
20410
20411     @Override
20412     public boolean isUserRunning(int userId, boolean orStopped) {
20413         if (checkCallingPermission(INTERACT_ACROSS_USERS)
20414                 != PackageManager.PERMISSION_GRANTED) {
20415             String msg = "Permission Denial: isUserRunning() from pid="
20416                     + Binder.getCallingPid()
20417                     + ", uid=" + Binder.getCallingUid()
20418                     + " requires " + INTERACT_ACROSS_USERS;
20419             Slog.w(TAG, msg);
20420             throw new SecurityException(msg);
20421         }
20422         synchronized (this) {
20423             return isUserRunningLocked(userId, orStopped);
20424         }
20425     }
20426
20427     boolean isUserRunningLocked(int userId, boolean orStopped) {
20428         UserState state = mStartedUsers.get(userId);
20429         if (state == null) {
20430             return false;
20431         }
20432         if (orStopped) {
20433             return true;
20434         }
20435         return state.mState != UserState.STATE_STOPPING
20436                 && state.mState != UserState.STATE_SHUTDOWN;
20437     }
20438
20439     @Override
20440     public int[] getRunningUserIds() {
20441         if (checkCallingPermission(INTERACT_ACROSS_USERS)
20442                 != PackageManager.PERMISSION_GRANTED) {
20443             String msg = "Permission Denial: isUserRunning() from pid="
20444                     + Binder.getCallingPid()
20445                     + ", uid=" + Binder.getCallingUid()
20446                     + " requires " + INTERACT_ACROSS_USERS;
20447             Slog.w(TAG, msg);
20448             throw new SecurityException(msg);
20449         }
20450         synchronized (this) {
20451             return mStartedUserArray;
20452         }
20453     }
20454
20455     private void updateStartedUserArrayLocked() {
20456         int num = 0;
20457         for (int i=0; i<mStartedUsers.size();  i++) {
20458             UserState uss = mStartedUsers.valueAt(i);
20459             // This list does not include stopping users.
20460             if (uss.mState != UserState.STATE_STOPPING
20461                     && uss.mState != UserState.STATE_SHUTDOWN) {
20462                 num++;
20463             }
20464         }
20465         mStartedUserArray = new int[num];
20466         num = 0;
20467         for (int i=0; i<mStartedUsers.size();  i++) {
20468             UserState uss = mStartedUsers.valueAt(i);
20469             if (uss.mState != UserState.STATE_STOPPING
20470                     && uss.mState != UserState.STATE_SHUTDOWN) {
20471                 mStartedUserArray[num] = mStartedUsers.keyAt(i);
20472                 num++;
20473             }
20474         }
20475     }
20476
20477     @Override
20478     public void registerUserSwitchObserver(IUserSwitchObserver observer) {
20479         if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
20480                 != PackageManager.PERMISSION_GRANTED) {
20481             String msg = "Permission Denial: registerUserSwitchObserver() from pid="
20482                     + Binder.getCallingPid()
20483                     + ", uid=" + Binder.getCallingUid()
20484                     + " requires " + INTERACT_ACROSS_USERS_FULL;
20485             Slog.w(TAG, msg);
20486             throw new SecurityException(msg);
20487         }
20488
20489         mUserSwitchObservers.register(observer);
20490     }
20491
20492     @Override
20493     public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
20494         mUserSwitchObservers.unregister(observer);
20495     }
20496
20497     int[] getUsersLocked() {
20498         UserManagerService ums = getUserManagerLocked();
20499         return ums != null ? ums.getUserIds() : new int[] { 0 };
20500     }
20501
20502     UserManagerService getUserManagerLocked() {
20503         if (mUserManager == null) {
20504             IBinder b = ServiceManager.getService(Context.USER_SERVICE);
20505             mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
20506         }
20507         return mUserManager;
20508     }
20509
20510     private int applyUserId(int uid, int userId) {
20511         return UserHandle.getUid(userId, uid);
20512     }
20513
20514     ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
20515         if (info == null) return null;
20516         ApplicationInfo newInfo = new ApplicationInfo(info);
20517         newInfo.uid = applyUserId(info.uid, userId);
20518         newInfo.dataDir = Environment
20519                 .getDataUserPackageDirectory(info.volumeUuid, userId, info.packageName)
20520                 .getAbsolutePath();
20521         return newInfo;
20522     }
20523
20524     ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
20525         if (aInfo == null
20526                 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
20527             return aInfo;
20528         }
20529
20530         ActivityInfo info = new ActivityInfo(aInfo);
20531         info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
20532         return info;
20533     }
20534
20535     private final class LocalService extends ActivityManagerInternal {
20536         @Override
20537         public void onWakefulnessChanged(int wakefulness) {
20538             ActivityManagerService.this.onWakefulnessChanged(wakefulness);
20539         }
20540
20541         @Override
20542         public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
20543                 String processName, String abiOverride, int uid, Runnable crashHandler) {
20544             return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
20545                     processName, abiOverride, uid, crashHandler);
20546         }
20547
20548         @Override
20549         public SleepToken acquireSleepToken(String tag) {
20550             Preconditions.checkNotNull(tag);
20551
20552             synchronized (ActivityManagerService.this) {
20553                 SleepTokenImpl token = new SleepTokenImpl(tag);
20554                 mSleepTokens.add(token);
20555                 updateSleepIfNeededLocked();
20556                 return token;
20557             }
20558         }
20559
20560         @Override
20561         public ComponentName getHomeActivityForUser(int userId) {
20562             synchronized (ActivityManagerService.this) {
20563                 ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
20564                 return homeActivity == null ? null : homeActivity.realActivity;
20565             }
20566         }
20567     }
20568
20569     private final class SleepTokenImpl extends SleepToken {
20570         private final String mTag;
20571         private final long mAcquireTime;
20572
20573         public SleepTokenImpl(String tag) {
20574             mTag = tag;
20575             mAcquireTime = SystemClock.uptimeMillis();
20576         }
20577
20578         @Override
20579         public void release() {
20580             synchronized (ActivityManagerService.this) {
20581                 if (mSleepTokens.remove(this)) {
20582                     updateSleepIfNeededLocked();
20583                 }
20584             }
20585         }
20586
20587         @Override
20588         public String toString() {
20589             return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
20590         }
20591     }
20592
20593     /**
20594      * An implementation of IAppTask, that allows an app to manage its own tasks via
20595      * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
20596      * only the process that calls getAppTasks() can call the AppTask methods.
20597      */
20598     class AppTaskImpl extends IAppTask.Stub {
20599         private int mTaskId;
20600         private int mCallingUid;
20601
20602         public AppTaskImpl(int taskId, int callingUid) {
20603             mTaskId = taskId;
20604             mCallingUid = callingUid;
20605         }
20606
20607         private void checkCaller() {
20608             if (mCallingUid != Binder.getCallingUid()) {
20609                 throw new SecurityException("Caller " + mCallingUid
20610                         + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
20611             }
20612         }
20613
20614         @Override
20615         public void finishAndRemoveTask() {
20616             checkCaller();
20617
20618             synchronized (ActivityManagerService.this) {
20619                 long origId = Binder.clearCallingIdentity();
20620                 try {
20621                     if (!removeTaskByIdLocked(mTaskId, false)) {
20622                         throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20623                     }
20624                 } finally {
20625                     Binder.restoreCallingIdentity(origId);
20626                 }
20627             }
20628         }
20629
20630         @Override
20631         public ActivityManager.RecentTaskInfo getTaskInfo() {
20632             checkCaller();
20633
20634             synchronized (ActivityManagerService.this) {
20635                 long origId = Binder.clearCallingIdentity();
20636                 try {
20637                     TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
20638                     if (tr == null) {
20639                         throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20640                     }
20641                     return createRecentTaskInfoFromTaskRecord(tr);
20642                 } finally {
20643                     Binder.restoreCallingIdentity(origId);
20644                 }
20645             }
20646         }
20647
20648         @Override
20649         public void moveToFront() {
20650             checkCaller();
20651             // Will bring task to front if it already has a root activity.
20652             startActivityFromRecentsInner(mTaskId, null);
20653         }
20654
20655         @Override
20656         public int startActivity(IBinder whoThread, String callingPackage,
20657                 Intent intent, String resolvedType, Bundle options) {
20658             checkCaller();
20659
20660             int callingUser = UserHandle.getCallingUserId();
20661             TaskRecord tr;
20662             IApplicationThread appThread;
20663             synchronized (ActivityManagerService.this) {
20664                 tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
20665                 if (tr == null) {
20666                     throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20667                 }
20668                 appThread = ApplicationThreadNative.asInterface(whoThread);
20669                 if (appThread == null) {
20670                     throw new IllegalArgumentException("Bad app thread " + appThread);
20671                 }
20672             }
20673             return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent,
20674                     resolvedType, null, null, null, null, 0, 0, null, null,
20675                     null, options, false, callingUser, null, tr);
20676         }
20677
20678         @Override
20679         public void setExcludeFromRecents(boolean exclude) {
20680             checkCaller();
20681
20682             synchronized (ActivityManagerService.this) {
20683                 long origId = Binder.clearCallingIdentity();
20684                 try {
20685                     TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
20686                     if (tr == null) {
20687                         throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20688                     }
20689                     Intent intent = tr.getBaseIntent();
20690                     if (exclude) {
20691                         intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
20692                     } else {
20693                         intent.setFlags(intent.getFlags()
20694                                 & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
20695                     }
20696                 } finally {
20697                     Binder.restoreCallingIdentity(origId);
20698                 }
20699             }
20700         }
20701     }
20702 }