OSDN Git Service

Fix issue #25357209: Could not send SMS or MMS messages, had to reboot
[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     // How long we wait for an attached process to publish its content providers
320     // before we decide it must be hung.
321     static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000;
322
323     // How long we wait for a launched process to attach to the activity manager
324     // before we decide it's never going to come up for real, when the process was
325     // started with a wrapper for instrumentation (such as Valgrind) because it
326     // could take much longer than usual.
327     static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
328
329     // How long to wait after going idle before forcing apps to GC.
330     static final int GC_TIMEOUT = 5*1000;
331
332     // The minimum amount of time between successive GC requests for a process.
333     static final int GC_MIN_INTERVAL = 60*1000;
334
335     // The minimum amount of time between successive PSS requests for a process.
336     static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
337
338     // The minimum amount of time between successive PSS requests for a process
339     // when the request is due to the memory state being lowered.
340     static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
341
342     // The rate at which we check for apps using excessive power -- 15 mins.
343     static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
344
345     // The minimum sample duration we will allow before deciding we have
346     // enough data on wake locks to start killing things.
347     static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
348
349     // The minimum sample duration we will allow before deciding we have
350     // enough data on CPU usage to start killing things.
351     static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
352
353     // How long we allow a receiver to run before giving up on it.
354     static final int BROADCAST_FG_TIMEOUT = 10*1000;
355     static final int BROADCAST_BG_TIMEOUT = 60*1000;
356
357     // How long we wait until we timeout on key dispatching.
358     static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
359
360     // How long we wait until we timeout on key dispatching during instrumentation.
361     static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
362
363     // Amount of time we wait for observers to handle a user switch before
364     // giving up on them and unfreezing the screen.
365     static final int USER_SWITCH_TIMEOUT = 2*1000;
366
367     // This is the amount of time an app needs to be running a foreground service before
368     // we will consider it to be doing interaction for usage stats.
369     static final int SERVICE_USAGE_INTERACTION_TIME = 30*60*1000;
370
371     // Maximum amount of time we will allow to elapse before re-reporting usage stats
372     // interaction with foreground processes.
373     static final long USAGE_STATS_INTERACTION_INTERVAL = 24*60*60*1000L;
374
375     // Maximum number of users we allow to be running at a time.
376     static final int MAX_RUNNING_USERS = 3;
377
378     // How long to wait in getAssistContextExtras for the activity and foreground services
379     // to respond with the result.
380     static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
381
382     // How long top wait when going through the modern assist (which doesn't need to block
383     // on getting this result before starting to launch its UI).
384     static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
385
386     // Maximum number of persisted Uri grants a package is allowed
387     static final int MAX_PERSISTED_URI_GRANTS = 128;
388
389     static final int MY_PID = Process.myPid();
390
391     static final String[] EMPTY_STRING_ARRAY = new String[0];
392
393     // How many bytes to write into the dropbox log before truncating
394     static final int DROPBOX_MAX_SIZE = 256 * 1024;
395
396     // Access modes for handleIncomingUser.
397     static final int ALLOW_NON_FULL = 0;
398     static final int ALLOW_NON_FULL_IN_PROFILE = 1;
399     static final int ALLOW_FULL_ONLY = 2;
400
401     static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000;
402
403     // Delay in notifying task stack change listeners (in millis)
404     static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 1000;
405
406     // Necessary ApplicationInfo flags to mark an app as persistent
407     private static final int PERSISTENT_MASK =
408             ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
409
410
411     // Delay to disable app launch boost
412     static final int APP_BOOST_MESSAGE_DELAY = 3000;
413     // Lower delay than APP_BOOST_MESSAGE_DELAY to disable the boost
414     static final int APP_BOOST_TIMEOUT = 2500;
415
416     private static native int nativeMigrateToBoost();
417     private static native int nativeMigrateFromBoost();
418     private boolean mIsBoosted = false;
419     private long mBoostStartTime = 0;
420
421     /** All system services */
422     SystemServiceManager mSystemServiceManager;
423
424     private Installer mInstaller;
425
426     /** Run all ActivityStacks through this */
427     ActivityStackSupervisor mStackSupervisor;
428
429     /** Task stack change listeners. */
430     private RemoteCallbackList<ITaskStackListener> mTaskStackListeners =
431             new RemoteCallbackList<ITaskStackListener>();
432
433     public IntentFirewall mIntentFirewall;
434
435     // Whether we should show our dialogs (ANR, crash, etc) or just perform their
436     // default actuion automatically.  Important for devices without direct input
437     // devices.
438     private boolean mShowDialogs = true;
439
440     BroadcastQueue mFgBroadcastQueue;
441     BroadcastQueue mBgBroadcastQueue;
442     // Convenient for easy iteration over the queues. Foreground is first
443     // so that dispatch of foreground broadcasts gets precedence.
444     final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
445
446     BroadcastQueue broadcastQueueForIntent(Intent intent) {
447         final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
448         if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
449                 "Broadcast intent " + intent + " on "
450                 + (isFg ? "foreground" : "background") + " queue");
451         return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
452     }
453
454     /**
455      * Activity we have told the window manager to have key focus.
456      */
457     ActivityRecord mFocusedActivity = null;
458
459     /**
460      * User id of the last activity mFocusedActivity was set to.
461      */
462     private int mLastFocusedUserId;
463
464     /**
465      * If non-null, we are tracking the time the user spends in the currently focused app.
466      */
467     private AppTimeTracker mCurAppTimeTracker;
468
469     /**
470      * List of intents that were used to start the most recent tasks.
471      */
472     private final RecentTasks mRecentTasks;
473
474     /**
475      * For addAppTask: cached of the last activity component that was added.
476      */
477     ComponentName mLastAddedTaskComponent;
478
479     /**
480      * For addAppTask: cached of the last activity uid that was added.
481      */
482     int mLastAddedTaskUid;
483
484     /**
485      * For addAppTask: cached of the last ActivityInfo that was added.
486      */
487     ActivityInfo mLastAddedTaskActivity;
488
489     /**
490      * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId.
491      */
492     SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
493
494     /**
495      * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
496      */
497     String mDeviceOwnerName;
498
499     public class PendingAssistExtras extends Binder implements Runnable {
500         public final ActivityRecord activity;
501         public final Bundle extras;
502         public final Intent intent;
503         public final String hint;
504         public final IResultReceiver receiver;
505         public final int userHandle;
506         public boolean haveResult = false;
507         public Bundle result = null;
508         public AssistStructure structure = null;
509         public AssistContent content = null;
510         public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
511                 String _hint, IResultReceiver _receiver, int _userHandle) {
512             activity = _activity;
513             extras = _extras;
514             intent = _intent;
515             hint = _hint;
516             receiver = _receiver;
517             userHandle = _userHandle;
518         }
519         @Override
520         public void run() {
521             Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
522             synchronized (this) {
523                 haveResult = true;
524                 notifyAll();
525             }
526             pendingAssistExtrasTimedOut(this);
527         }
528     }
529
530     final ArrayList<PendingAssistExtras> mPendingAssistExtras
531             = new ArrayList<PendingAssistExtras>();
532
533     /**
534      * Process management.
535      */
536     final ProcessList mProcessList = new ProcessList();
537
538     /**
539      * All of the applications we currently have running organized by name.
540      * The keys are strings of the application package name (as
541      * returned by the package manager), and the keys are ApplicationRecord
542      * objects.
543      */
544     final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
545
546     /**
547      * Tracking long-term execution of processes to look for abuse and other
548      * bad app behavior.
549      */
550     final ProcessStatsService mProcessStats;
551
552     /**
553      * The currently running isolated processes.
554      */
555     final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
556
557     /**
558      * Counter for assigning isolated process uids, to avoid frequently reusing the
559      * same ones.
560      */
561     int mNextIsolatedProcessUid = 0;
562
563     /**
564      * The currently running heavy-weight process, if any.
565      */
566     ProcessRecord mHeavyWeightProcess = null;
567
568     /**
569      * The last time that various processes have crashed.
570      */
571     final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
572
573     /**
574      * Information about a process that is currently marked as bad.
575      */
576     static final class BadProcessInfo {
577         BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
578             this.time = time;
579             this.shortMsg = shortMsg;
580             this.longMsg = longMsg;
581             this.stack = stack;
582         }
583
584         final long time;
585         final String shortMsg;
586         final String longMsg;
587         final String stack;
588     }
589
590     /**
591      * Set of applications that we consider to be bad, and will reject
592      * incoming broadcasts from (which the user has no control over).
593      * Processes are added to this set when they have crashed twice within
594      * a minimum amount of time; they are removed from it when they are
595      * later restarted (hopefully due to some user action).  The value is the
596      * time it was added to the list.
597      */
598     final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
599
600     /**
601      * All of the processes we currently have running organized by pid.
602      * The keys are the pid running the application.
603      *
604      * <p>NOTE: This object is protected by its own lock, NOT the global
605      * activity manager lock!
606      */
607     final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
608
609     /**
610      * All of the processes that have been forced to be foreground.  The key
611      * is the pid of the caller who requested it (we hold a death
612      * link on it).
613      */
614     abstract class ForegroundToken implements IBinder.DeathRecipient {
615         int pid;
616         IBinder token;
617     }
618     final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
619
620     /**
621      * List of records for processes that someone had tried to start before the
622      * system was ready.  We don't start them at that point, but ensure they
623      * are started by the time booting is complete.
624      */
625     final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
626
627     /**
628      * List of persistent applications that are in the process
629      * of being started.
630      */
631     final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
632
633     /**
634      * Processes that are being forcibly torn down.
635      */
636     final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
637
638     /**
639      * List of running applications, sorted by recent usage.
640      * The first entry in the list is the least recently used.
641      */
642     final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
643
644     /**
645      * Where in mLruProcesses that the processes hosting activities start.
646      */
647     int mLruProcessActivityStart = 0;
648
649     /**
650      * Where in mLruProcesses that the processes hosting services start.
651      * This is after (lower index) than mLruProcessesActivityStart.
652      */
653     int mLruProcessServiceStart = 0;
654
655     /**
656      * List of processes that should gc as soon as things are idle.
657      */
658     final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
659
660     /**
661      * Processes we want to collect PSS data from.
662      */
663     final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
664
665     /**
666      * Last time we requested PSS data of all processes.
667      */
668     long mLastFullPssTime = SystemClock.uptimeMillis();
669
670     /**
671      * If set, the next time we collect PSS data we should do a full collection
672      * with data from native processes and the kernel.
673      */
674     boolean mFullPssPending = false;
675
676     /**
677      * This is the process holding what we currently consider to be
678      * the "home" activity.
679      */
680     ProcessRecord mHomeProcess;
681
682     /**
683      * This is the process holding the activity the user last visited that
684      * is in a different process from the one they are currently in.
685      */
686     ProcessRecord mPreviousProcess;
687
688     /**
689      * The time at which the previous process was last visible.
690      */
691     long mPreviousProcessVisibleTime;
692
693     /**
694      * Track all uids that have actively running processes.
695      */
696     final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
697
698     /**
699      * Which users have been started, so are allowed to run code.
700      */
701     final SparseArray<UserState> mStartedUsers = new SparseArray<>();
702
703     /**
704      * LRU list of history of current users.  Most recently current is at the end.
705      */
706     final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
707
708     /**
709      * Constant array of the users that are currently started.
710      */
711     int[] mStartedUserArray = new int[] { 0 };
712
713     /**
714      * Registered observers of the user switching mechanics.
715      */
716     final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
717             = new RemoteCallbackList<IUserSwitchObserver>();
718
719     /**
720      * Currently active user switch.
721      */
722     Object mCurUserSwitchCallback;
723
724     /**
725      * Packages that the user has asked to have run in screen size
726      * compatibility mode instead of filling the screen.
727      */
728     final CompatModePackages mCompatModePackages;
729
730     /**
731      * Set of IntentSenderRecord objects that are currently active.
732      */
733     final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
734             = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
735
736     /**
737      * Fingerprints (hashCode()) of stack traces that we've
738      * already logged DropBox entries for.  Guarded by itself.  If
739      * something (rogue user app) forces this over
740      * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
741      */
742     private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
743     private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
744
745     /**
746      * Strict Mode background batched logging state.
747      *
748      * The string buffer is guarded by itself, and its lock is also
749      * used to determine if another batched write is already
750      * in-flight.
751      */
752     private final StringBuilder mStrictModeBuffer = new StringBuilder();
753
754     /**
755      * Keeps track of all IIntentReceivers that have been registered for broadcasts.
756      * Hash keys are the receiver IBinder, hash value is a ReceiverList.
757      */
758     final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
759
760     /**
761      * Resolver for broadcast intents to registered receivers.
762      * Holds BroadcastFilter (subclass of IntentFilter).
763      */
764     final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
765             = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
766         @Override
767         protected boolean allowFilterResult(
768                 BroadcastFilter filter, List<BroadcastFilter> dest) {
769             IBinder target = filter.receiverList.receiver.asBinder();
770             for (int i = dest.size() - 1; i >= 0; i--) {
771                 if (dest.get(i).receiverList.receiver.asBinder() == target) {
772                     return false;
773                 }
774             }
775             return true;
776         }
777
778         @Override
779         protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
780             if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
781                     || userId == filter.owningUserId) {
782                 return super.newResult(filter, match, userId);
783             }
784             return null;
785         }
786
787         @Override
788         protected BroadcastFilter[] newArray(int size) {
789             return new BroadcastFilter[size];
790         }
791
792         @Override
793         protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
794             return packageName.equals(filter.packageName);
795         }
796     };
797
798     /**
799      * State of all active sticky broadcasts per user.  Keys are the action of the
800      * sticky Intent, values are an ArrayList of all broadcasted intents with
801      * that action (which should usually be one).  The SparseArray is keyed
802      * by the user ID the sticky is for, and can include UserHandle.USER_ALL
803      * for stickies that are sent to all users.
804      */
805     final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
806             new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
807
808     final ActiveServices mServices;
809
810     final static class Association {
811         final int mSourceUid;
812         final String mSourceProcess;
813         final int mTargetUid;
814         final ComponentName mTargetComponent;
815         final String mTargetProcess;
816
817         int mCount;
818         long mTime;
819
820         int mNesting;
821         long mStartTime;
822
823         Association(int sourceUid, String sourceProcess, int targetUid,
824                 ComponentName targetComponent, String targetProcess) {
825             mSourceUid = sourceUid;
826             mSourceProcess = sourceProcess;
827             mTargetUid = targetUid;
828             mTargetComponent = targetComponent;
829             mTargetProcess = targetProcess;
830         }
831     }
832
833     /**
834      * When service association tracking is enabled, this is all of the associations we
835      * have seen.  Mapping is target uid -> target component -> source uid -> source process name
836      * -> association data.
837      */
838     final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
839             mAssociations = new SparseArray<>();
840     boolean mTrackingAssociations;
841
842     /**
843      * Backup/restore process management
844      */
845     String mBackupAppName = null;
846     BackupRecord mBackupTarget = null;
847
848     final ProviderMap mProviderMap;
849
850     /**
851      * List of content providers who have clients waiting for them.  The
852      * application is currently being launched and the provider will be
853      * removed from this list once it is published.
854      */
855     final ArrayList<ContentProviderRecord> mLaunchingProviders
856             = new ArrayList<ContentProviderRecord>();
857
858     /**
859      * File storing persisted {@link #mGrantedUriPermissions}.
860      */
861     private final AtomicFile mGrantFile;
862
863     /** XML constants used in {@link #mGrantFile} */
864     private static final String TAG_URI_GRANTS = "uri-grants";
865     private static final String TAG_URI_GRANT = "uri-grant";
866     private static final String ATTR_USER_HANDLE = "userHandle";
867     private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
868     private static final String ATTR_TARGET_USER_ID = "targetUserId";
869     private static final String ATTR_SOURCE_PKG = "sourcePkg";
870     private static final String ATTR_TARGET_PKG = "targetPkg";
871     private static final String ATTR_URI = "uri";
872     private static final String ATTR_MODE_FLAGS = "modeFlags";
873     private static final String ATTR_CREATED_TIME = "createdTime";
874     private static final String ATTR_PREFIX = "prefix";
875
876     /**
877      * Global set of specific {@link Uri} permissions that have been granted.
878      * This optimized lookup structure maps from {@link UriPermission#targetUid}
879      * to {@link UriPermission#uri} to {@link UriPermission}.
880      */
881     @GuardedBy("this")
882     private final SparseArray<ArrayMap<GrantUri, UriPermission>>
883             mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
884
885     public static class GrantUri {
886         public final int sourceUserId;
887         public final Uri uri;
888         public boolean prefix;
889
890         public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
891             this.sourceUserId = sourceUserId;
892             this.uri = uri;
893             this.prefix = prefix;
894         }
895
896         @Override
897         public int hashCode() {
898             int hashCode = 1;
899             hashCode = 31 * hashCode + sourceUserId;
900             hashCode = 31 * hashCode + uri.hashCode();
901             hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
902             return hashCode;
903         }
904
905         @Override
906         public boolean equals(Object o) {
907             if (o instanceof GrantUri) {
908                 GrantUri other = (GrantUri) o;
909                 return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
910                         && prefix == other.prefix;
911             }
912             return false;
913         }
914
915         @Override
916         public String toString() {
917             String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
918             if (prefix) result += " [prefix]";
919             return result;
920         }
921
922         public String toSafeString() {
923             String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
924             if (prefix) result += " [prefix]";
925             return result;
926         }
927
928         public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
929             return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
930                     ContentProvider.getUriWithoutUserId(uri), false);
931         }
932     }
933
934     CoreSettingsObserver mCoreSettingsObserver;
935
936     /**
937      * Thread-local storage used to carry caller permissions over through
938      * indirect content-provider access.
939      */
940     private class Identity {
941         public final IBinder token;
942         public final int pid;
943         public final int uid;
944
945         Identity(IBinder _token, int _pid, int _uid) {
946             token = _token;
947             pid = _pid;
948             uid = _uid;
949         }
950     }
951
952     private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
953
954     /**
955      * All information we have collected about the runtime performance of
956      * any user id that can impact battery performance.
957      */
958     final BatteryStatsService mBatteryStatsService;
959
960     /**
961      * Information about component usage
962      */
963     UsageStatsManagerInternal mUsageStatsService;
964
965     /**
966      * Access to DeviceIdleController service.
967      */
968     DeviceIdleController.LocalService mLocalDeviceIdleController;
969
970     /**
971      * Information about and control over application operations
972      */
973     final AppOpsService mAppOpsService;
974
975     /**
976      * Save recent tasks information across reboots.
977      */
978     final TaskPersister mTaskPersister;
979
980     /**
981      * Current configuration information.  HistoryRecord objects are given
982      * a reference to this object to indicate which configuration they are
983      * currently running in, so this object must be kept immutable.
984      */
985     Configuration mConfiguration = new Configuration();
986
987     /**
988      * Current sequencing integer of the configuration, for skipping old
989      * configurations.
990      */
991     int mConfigurationSeq = 0;
992
993     /**
994      * Hardware-reported OpenGLES version.
995      */
996     final int GL_ES_VERSION;
997
998     /**
999      * List of initialization arguments to pass to all processes when binding applications to them.
1000      * For example, references to the commonly used services.
1001      */
1002     HashMap<String, IBinder> mAppBindArgs;
1003
1004     /**
1005      * Temporary to avoid allocations.  Protected by main lock.
1006      */
1007     final StringBuilder mStringBuilder = new StringBuilder(256);
1008
1009     /**
1010      * Used to control how we initialize the service.
1011      */
1012     ComponentName mTopComponent;
1013     String mTopAction = Intent.ACTION_MAIN;
1014     String mTopData;
1015     boolean mProcessesReady = false;
1016     boolean mSystemReady = false;
1017     boolean mBooting = false;
1018     boolean mCallFinishBooting = false;
1019     boolean mBootAnimationComplete = false;
1020     boolean mWaitingUpdate = false;
1021     boolean mDidUpdate = false;
1022     boolean mOnBattery = false;
1023     boolean mLaunchWarningShown = false;
1024
1025     Context mContext;
1026
1027     int mFactoryTest;
1028
1029     boolean mCheckedForSetup;
1030
1031     /**
1032      * The time at which we will allow normal application switches again,
1033      * after a call to {@link #stopAppSwitches()}.
1034      */
1035     long mAppSwitchesAllowedTime;
1036
1037     /**
1038      * This is set to true after the first switch after mAppSwitchesAllowedTime
1039      * is set; any switches after that will clear the time.
1040      */
1041     boolean mDidAppSwitch;
1042
1043     /**
1044      * Last time (in realtime) at which we checked for power usage.
1045      */
1046     long mLastPowerCheckRealtime;
1047
1048     /**
1049      * Last time (in uptime) at which we checked for power usage.
1050      */
1051     long mLastPowerCheckUptime;
1052
1053     /**
1054      * Set while we are wanting to sleep, to prevent any
1055      * activities from being started/resumed.
1056      */
1057     private boolean mSleeping = false;
1058
1059     /**
1060      * The process state used for processes that are running the top activities.
1061      * This changes between TOP and TOP_SLEEPING to following mSleeping.
1062      */
1063     int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1064
1065     /**
1066      * Set while we are running a voice interaction.  This overrides
1067      * sleeping while it is active.
1068      */
1069     private IVoiceInteractionSession mRunningVoice;
1070
1071     /**
1072      * For some direct access we need to power manager.
1073      */
1074     PowerManagerInternal mLocalPowerManager;
1075
1076     /**
1077      * We want to hold a wake lock while running a voice interaction session, since
1078      * this may happen with the screen off and we need to keep the CPU running to
1079      * be able to continue to interact with the user.
1080      */
1081     PowerManager.WakeLock mVoiceWakeLock;
1082
1083     /**
1084      * State of external calls telling us if the device is awake or asleep.
1085      */
1086     private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1087
1088     /**
1089      * A list of tokens that cause the top activity to be put to sleep.
1090      * They are used by components that may hide and block interaction with underlying
1091      * activities.
1092      */
1093     final ArrayList<SleepToken> mSleepTokens = new ArrayList<SleepToken>();
1094
1095     static final int LOCK_SCREEN_HIDDEN = 0;
1096     static final int LOCK_SCREEN_LEAVING = 1;
1097     static final int LOCK_SCREEN_SHOWN = 2;
1098     /**
1099      * State of external call telling us if the lock screen is shown.
1100      */
1101     int mLockScreenShown = LOCK_SCREEN_HIDDEN;
1102
1103     /**
1104      * Set if we are shutting down the system, similar to sleeping.
1105      */
1106     boolean mShuttingDown = false;
1107
1108     /**
1109      * Current sequence id for oom_adj computation traversal.
1110      */
1111     int mAdjSeq = 0;
1112
1113     /**
1114      * Current sequence id for process LRU updating.
1115      */
1116     int mLruSeq = 0;
1117
1118     /**
1119      * Keep track of the non-cached/empty process we last found, to help
1120      * determine how to distribute cached/empty processes next time.
1121      */
1122     int mNumNonCachedProcs = 0;
1123
1124     /**
1125      * Keep track of the number of cached hidden procs, to balance oom adj
1126      * distribution between those and empty procs.
1127      */
1128     int mNumCachedHiddenProcs = 0;
1129
1130     /**
1131      * Keep track of the number of service processes we last found, to
1132      * determine on the next iteration which should be B services.
1133      */
1134     int mNumServiceProcs = 0;
1135     int mNewNumAServiceProcs = 0;
1136     int mNewNumServiceProcs = 0;
1137
1138     /**
1139      * Allow the current computed overall memory level of the system to go down?
1140      * This is set to false when we are killing processes for reasons other than
1141      * memory management, so that the now smaller process list will not be taken as
1142      * an indication that memory is tighter.
1143      */
1144     boolean mAllowLowerMemLevel = false;
1145
1146     /**
1147      * The last computed memory level, for holding when we are in a state that
1148      * processes are going away for other reasons.
1149      */
1150     int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1151
1152     /**
1153      * The last total number of process we have, to determine if changes actually look
1154      * like a shrinking number of process due to lower RAM.
1155      */
1156     int mLastNumProcesses;
1157
1158     /**
1159      * The uptime of the last time we performed idle maintenance.
1160      */
1161     long mLastIdleTime = SystemClock.uptimeMillis();
1162
1163     /**
1164      * Total time spent with RAM that has been added in the past since the last idle time.
1165      */
1166     long mLowRamTimeSinceLastIdle = 0;
1167
1168     /**
1169      * If RAM is currently low, when that horrible situation started.
1170      */
1171     long mLowRamStartTime = 0;
1172
1173     /**
1174      * For reporting to battery stats the current top application.
1175      */
1176     private String mCurResumedPackage = null;
1177     private int mCurResumedUid = -1;
1178
1179     /**
1180      * For reporting to battery stats the apps currently running foreground
1181      * service.  The ProcessMap is package/uid tuples; each of these contain
1182      * an array of the currently foreground processes.
1183      */
1184     final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1185             = new ProcessMap<ArrayList<ProcessRecord>>();
1186
1187     /**
1188      * This is set if we had to do a delayed dexopt of an app before launching
1189      * it, to increase the ANR timeouts in that case.
1190      */
1191     boolean mDidDexOpt;
1192
1193     /**
1194      * Set if the systemServer made a call to enterSafeMode.
1195      */
1196     boolean mSafeMode;
1197
1198     /**
1199      * If true, we are running under a test environment so will sample PSS from processes
1200      * much more rapidly to try to collect better data when the tests are rapidly
1201      * running through apps.
1202      */
1203     boolean mTestPssMode = false;
1204
1205     String mDebugApp = null;
1206     boolean mWaitForDebugger = false;
1207     boolean mDebugTransient = false;
1208     String mOrigDebugApp = null;
1209     boolean mOrigWaitForDebugger = false;
1210     boolean mAlwaysFinishActivities = false;
1211     IActivityController mController = null;
1212     String mProfileApp = null;
1213     ProcessRecord mProfileProc = null;
1214     String mProfileFile;
1215     ParcelFileDescriptor mProfileFd;
1216     int mSamplingInterval = 0;
1217     boolean mAutoStopProfiler = false;
1218     int mProfileType = 0;
1219     String mOpenGlTraceApp = null;
1220     final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1221     String mMemWatchDumpProcName;
1222     String mMemWatchDumpFile;
1223     int mMemWatchDumpPid;
1224     int mMemWatchDumpUid;
1225
1226     final long[] mTmpLong = new long[1];
1227
1228     static final class ProcessChangeItem {
1229         static final int CHANGE_ACTIVITIES = 1<<0;
1230         static final int CHANGE_PROCESS_STATE = 1<<1;
1231         int changes;
1232         int uid;
1233         int pid;
1234         int processState;
1235         boolean foregroundActivities;
1236     }
1237
1238     final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1239     ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1240
1241     final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1242     final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1243
1244     final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1245     UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1246
1247     final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1248     final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1249
1250     /**
1251      * Runtime CPU use collection thread.  This object's lock is used to
1252      * perform synchronization with the thread (notifying it to run).
1253      */
1254     final Thread mProcessCpuThread;
1255
1256     /**
1257      * Used to collect per-process CPU use for ANRs, battery stats, etc.
1258      * Must acquire this object's lock when accessing it.
1259      * NOTE: this lock will be held while doing long operations (trawling
1260      * through all processes in /proc), so it should never be acquired by
1261      * any critical paths such as when holding the main activity manager lock.
1262      */
1263     final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1264             MONITOR_THREAD_CPU_USAGE);
1265     final AtomicLong mLastCpuTime = new AtomicLong(0);
1266     final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1267
1268     long mLastWriteTime = 0;
1269
1270     /**
1271      * Used to retain an update lock when the foreground activity is in
1272      * immersive mode.
1273      */
1274     final UpdateLock mUpdateLock = new UpdateLock("immersive");
1275
1276     /**
1277      * Set to true after the system has finished booting.
1278      */
1279     boolean mBooted = false;
1280
1281     int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1282     int mProcessLimitOverride = -1;
1283
1284     WindowManagerService mWindowManager;
1285
1286     final ActivityThread mSystemThread;
1287
1288     // Holds the current foreground user's id
1289     int mCurrentUserId = 0;
1290     // Holds the target user's id during a user switch
1291     int mTargetUserId = UserHandle.USER_NULL;
1292     // If there are multiple profiles for the current user, their ids are here
1293     // Currently only the primary user can have managed profiles
1294     int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1295
1296     /**
1297      * Mapping from each known user ID to the profile group ID it is associated with.
1298      */
1299     SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray();
1300
1301     private UserManagerService mUserManager;
1302
1303     private final class AppDeathRecipient implements IBinder.DeathRecipient {
1304         final ProcessRecord mApp;
1305         final int mPid;
1306         final IApplicationThread mAppThread;
1307
1308         AppDeathRecipient(ProcessRecord app, int pid,
1309                 IApplicationThread thread) {
1310             if (DEBUG_ALL) Slog.v(
1311                 TAG, "New death recipient " + this
1312                 + " for thread " + thread.asBinder());
1313             mApp = app;
1314             mPid = pid;
1315             mAppThread = thread;
1316         }
1317
1318         @Override
1319         public void binderDied() {
1320             if (DEBUG_ALL) Slog.v(
1321                 TAG, "Death received in " + this
1322                 + " for thread " + mAppThread.asBinder());
1323             synchronized(ActivityManagerService.this) {
1324                 appDiedLocked(mApp, mPid, mAppThread, true);
1325             }
1326         }
1327     }
1328
1329     static final int SHOW_ERROR_MSG = 1;
1330     static final int SHOW_NOT_RESPONDING_MSG = 2;
1331     static final int SHOW_FACTORY_ERROR_MSG = 3;
1332     static final int UPDATE_CONFIGURATION_MSG = 4;
1333     static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1334     static final int WAIT_FOR_DEBUGGER_MSG = 6;
1335     static final int SERVICE_TIMEOUT_MSG = 12;
1336     static final int UPDATE_TIME_ZONE = 13;
1337     static final int SHOW_UID_ERROR_MSG = 14;
1338     static final int SHOW_FINGERPRINT_ERROR_MSG = 15;
1339     static final int PROC_START_TIMEOUT_MSG = 20;
1340     static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1341     static final int KILL_APPLICATION_MSG = 22;
1342     static final int FINALIZE_PENDING_INTENT_MSG = 23;
1343     static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1344     static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1345     static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1346     static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1347     static final int CLEAR_DNS_CACHE_MSG = 28;
1348     static final int UPDATE_HTTP_PROXY_MSG = 29;
1349     static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1350     static final int DISPATCH_PROCESSES_CHANGED = 31;
1351     static final int DISPATCH_PROCESS_DIED = 32;
1352     static final int REPORT_MEM_USAGE_MSG = 33;
1353     static final int REPORT_USER_SWITCH_MSG = 34;
1354     static final int CONTINUE_USER_SWITCH_MSG = 35;
1355     static final int USER_SWITCH_TIMEOUT_MSG = 36;
1356     static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1357     static final int PERSIST_URI_GRANTS_MSG = 38;
1358     static final int REQUEST_ALL_PSS_MSG = 39;
1359     static final int START_PROFILES_MSG = 40;
1360     static final int UPDATE_TIME = 41;
1361     static final int SYSTEM_USER_START_MSG = 42;
1362     static final int SYSTEM_USER_CURRENT_MSG = 43;
1363     static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1364     static final int FINISH_BOOTING_MSG = 45;
1365     static final int START_USER_SWITCH_MSG = 46;
1366     static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1367     static final int DISMISS_DIALOG_MSG = 48;
1368     static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49;
1369     static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 50;
1370     static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 51;
1371     static final int DELETE_DUMPHEAP_MSG = 52;
1372     static final int FOREGROUND_PROFILE_CHANGED_MSG = 53;
1373     static final int DISPATCH_UIDS_CHANGED_MSG = 54;
1374     static final int REPORT_TIME_TRACKER_MSG = 55;
1375     static final int REPORT_USER_SWITCH_COMPLETE_MSG = 56;
1376     static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 57;
1377     static final int APP_BOOST_DEACTIVATE_MSG = 58;
1378     static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 59;
1379
1380     static final int FIRST_ACTIVITY_STACK_MSG = 100;
1381     static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1382     static final int FIRST_COMPAT_MODE_MSG = 300;
1383     static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1384
1385     CompatModeDialog mCompatModeDialog;
1386     long mLastMemUsageReportTime = 0;
1387
1388     /**
1389      * Flag whether the current user is a "monkey", i.e. whether
1390      * the UI is driven by a UI automation tool.
1391      */
1392     private boolean mUserIsMonkey;
1393
1394     /** Flag whether the device has a Recents UI */
1395     boolean mHasRecents;
1396
1397     /** The dimensions of the thumbnails in the Recents UI. */
1398     int mThumbnailWidth;
1399     int mThumbnailHeight;
1400
1401     final ServiceThread mHandlerThread;
1402     final MainHandler mHandler;
1403     final UiHandler mUiHandler;
1404
1405     final class UiHandler extends Handler {
1406         public UiHandler() {
1407             super(com.android.server.UiThread.get().getLooper(), null, true);
1408         }
1409
1410         @Override
1411         public void handleMessage(Message msg) {
1412             switch (msg.what) {
1413             case SHOW_ERROR_MSG: {
1414                 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1415                 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1416                         Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1417                 synchronized (ActivityManagerService.this) {
1418                     ProcessRecord proc = (ProcessRecord)data.get("app");
1419                     AppErrorResult res = (AppErrorResult) data.get("result");
1420                     if (proc != null && proc.crashDialog != null) {
1421                         Slog.e(TAG, "App already has crash dialog: " + proc);
1422                         if (res != null) {
1423                             res.set(0);
1424                         }
1425                         return;
1426                     }
1427                     boolean isBackground = (UserHandle.getAppId(proc.uid)
1428                             >= Process.FIRST_APPLICATION_UID
1429                             && proc.pid != MY_PID);
1430                     for (int userId : mCurrentProfileIds) {
1431                         isBackground &= (proc.userId != userId);
1432                     }
1433                     if (isBackground && !showBackground) {
1434                         Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1435                         if (res != null) {
1436                             res.set(0);
1437                         }
1438                         return;
1439                     }
1440                     if (mShowDialogs && !mSleeping && !mShuttingDown) {
1441                         Dialog d = new AppErrorDialog(mContext,
1442                                 ActivityManagerService.this, res, proc);
1443                         d.show();
1444                         proc.crashDialog = d;
1445                     } else {
1446                         // The device is asleep, so just pretend that the user
1447                         // saw a crash dialog and hit "force quit".
1448                         if (res != null) {
1449                             res.set(0);
1450                         }
1451                     }
1452                 }
1453
1454                 ensureBootCompleted();
1455             } break;
1456             case SHOW_NOT_RESPONDING_MSG: {
1457                 synchronized (ActivityManagerService.this) {
1458                     HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1459                     ProcessRecord proc = (ProcessRecord)data.get("app");
1460                     if (proc != null && proc.anrDialog != null) {
1461                         Slog.e(TAG, "App already has anr dialog: " + proc);
1462                         return;
1463                     }
1464
1465                     Intent intent = new Intent("android.intent.action.ANR");
1466                     if (!mProcessesReady) {
1467                         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1468                                 | Intent.FLAG_RECEIVER_FOREGROUND);
1469                     }
1470                     broadcastIntentLocked(null, null, intent,
1471                             null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1472                             null, false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1473
1474                     if (mShowDialogs) {
1475                         Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1476                                 mContext, proc, (ActivityRecord)data.get("activity"),
1477                                 msg.arg1 != 0);
1478                         d.show();
1479                         proc.anrDialog = d;
1480                     } else {
1481                         // Just kill the app if there is no dialog to be shown.
1482                         killAppAtUsersRequest(proc, null);
1483                     }
1484                 }
1485
1486                 ensureBootCompleted();
1487             } break;
1488             case SHOW_STRICT_MODE_VIOLATION_MSG: {
1489                 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1490                 synchronized (ActivityManagerService.this) {
1491                     ProcessRecord proc = (ProcessRecord) data.get("app");
1492                     if (proc == null) {
1493                         Slog.e(TAG, "App not found when showing strict mode dialog.");
1494                         break;
1495                     }
1496                     if (proc.crashDialog != null) {
1497                         Slog.e(TAG, "App already has strict mode dialog: " + proc);
1498                         return;
1499                     }
1500                     AppErrorResult res = (AppErrorResult) data.get("result");
1501                     if (mShowDialogs && !mSleeping && !mShuttingDown) {
1502                         Dialog d = new StrictModeViolationDialog(mContext,
1503                                 ActivityManagerService.this, res, proc);
1504                         d.show();
1505                         proc.crashDialog = d;
1506                     } else {
1507                         // The device is asleep, so just pretend that the user
1508                         // saw a crash dialog and hit "force quit".
1509                         res.set(0);
1510                     }
1511                 }
1512                 ensureBootCompleted();
1513             } break;
1514             case SHOW_FACTORY_ERROR_MSG: {
1515                 Dialog d = new FactoryErrorDialog(
1516                     mContext, msg.getData().getCharSequence("msg"));
1517                 d.show();
1518                 ensureBootCompleted();
1519             } break;
1520             case WAIT_FOR_DEBUGGER_MSG: {
1521                 synchronized (ActivityManagerService.this) {
1522                     ProcessRecord app = (ProcessRecord)msg.obj;
1523                     if (msg.arg1 != 0) {
1524                         if (!app.waitedForDebugger) {
1525                             Dialog d = new AppWaitingForDebuggerDialog(
1526                                     ActivityManagerService.this,
1527                                     mContext, app);
1528                             app.waitDialog = d;
1529                             app.waitedForDebugger = true;
1530                             d.show();
1531                         }
1532                     } else {
1533                         if (app.waitDialog != null) {
1534                             app.waitDialog.dismiss();
1535                             app.waitDialog = null;
1536                         }
1537                     }
1538                 }
1539             } break;
1540             case SHOW_UID_ERROR_MSG: {
1541                 if (mShowDialogs) {
1542                     AlertDialog d = new BaseErrorDialog(mContext);
1543                     d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1544                     d.setCancelable(false);
1545                     d.setTitle(mContext.getText(R.string.android_system_label));
1546                     d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1547                     d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1548                             obtainMessage(DISMISS_DIALOG_MSG, d));
1549                     d.show();
1550                 }
1551             } break;
1552             case SHOW_FINGERPRINT_ERROR_MSG: {
1553                 if (mShowDialogs) {
1554                     AlertDialog d = new BaseErrorDialog(mContext);
1555                     d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1556                     d.setCancelable(false);
1557                     d.setTitle(mContext.getText(R.string.android_system_label));
1558                     d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1559                     d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1560                             obtainMessage(DISMISS_DIALOG_MSG, d));
1561                     d.show();
1562                 }
1563             } break;
1564             case SHOW_COMPAT_MODE_DIALOG_MSG: {
1565                 synchronized (ActivityManagerService.this) {
1566                     ActivityRecord ar = (ActivityRecord) msg.obj;
1567                     if (mCompatModeDialog != null) {
1568                         if (mCompatModeDialog.mAppInfo.packageName.equals(
1569                                 ar.info.applicationInfo.packageName)) {
1570                             return;
1571                         }
1572                         mCompatModeDialog.dismiss();
1573                         mCompatModeDialog = null;
1574                     }
1575                     if (ar != null && false) {
1576                         if (mCompatModePackages.getPackageAskCompatModeLocked(
1577                                 ar.packageName)) {
1578                             int mode = mCompatModePackages.computeCompatModeLocked(
1579                                     ar.info.applicationInfo);
1580                             if (mode == ActivityManager.COMPAT_MODE_DISABLED
1581                                     || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1582                                 mCompatModeDialog = new CompatModeDialog(
1583                                         ActivityManagerService.this, mContext,
1584                                         ar.info.applicationInfo);
1585                                 mCompatModeDialog.show();
1586                             }
1587                         }
1588                     }
1589                 }
1590                 break;
1591             }
1592             case START_USER_SWITCH_MSG: {
1593                 showUserSwitchDialog(msg.arg1, (String) msg.obj);
1594                 break;
1595             }
1596             case DISMISS_DIALOG_MSG: {
1597                 final Dialog d = (Dialog) msg.obj;
1598                 d.dismiss();
1599                 break;
1600             }
1601             case DISPATCH_PROCESSES_CHANGED: {
1602                 dispatchProcessesChanged();
1603                 break;
1604             }
1605             case DISPATCH_PROCESS_DIED: {
1606                 final int pid = msg.arg1;
1607                 final int uid = msg.arg2;
1608                 dispatchProcessDied(pid, uid);
1609                 break;
1610             }
1611             case DISPATCH_UIDS_CHANGED_MSG: {
1612                 dispatchUidsChanged();
1613             } break;
1614             }
1615         }
1616     }
1617
1618     final class MainHandler extends Handler {
1619         public MainHandler(Looper looper) {
1620             super(looper, null, true);
1621         }
1622
1623         @Override
1624         public void handleMessage(Message msg) {
1625             switch (msg.what) {
1626             case UPDATE_CONFIGURATION_MSG: {
1627                 final ContentResolver resolver = mContext.getContentResolver();
1628                 Settings.System.putConfiguration(resolver, (Configuration) msg.obj);
1629             } break;
1630             case GC_BACKGROUND_PROCESSES_MSG: {
1631                 synchronized (ActivityManagerService.this) {
1632                     performAppGcsIfAppropriateLocked();
1633                 }
1634             } break;
1635             case SERVICE_TIMEOUT_MSG: {
1636                 if (mDidDexOpt) {
1637                     mDidDexOpt = false;
1638                     Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1639                     nmsg.obj = msg.obj;
1640                     mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1641                     return;
1642                 }
1643                 mServices.serviceTimeout((ProcessRecord)msg.obj);
1644             } break;
1645             case UPDATE_TIME_ZONE: {
1646                 synchronized (ActivityManagerService.this) {
1647                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1648                         ProcessRecord r = mLruProcesses.get(i);
1649                         if (r.thread != null) {
1650                             try {
1651                                 r.thread.updateTimeZone();
1652                             } catch (RemoteException ex) {
1653                                 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1654                             }
1655                         }
1656                     }
1657                 }
1658             } break;
1659             case CLEAR_DNS_CACHE_MSG: {
1660                 synchronized (ActivityManagerService.this) {
1661                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1662                         ProcessRecord r = mLruProcesses.get(i);
1663                         if (r.thread != null) {
1664                             try {
1665                                 r.thread.clearDnsCache();
1666                             } catch (RemoteException ex) {
1667                                 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1668                             }
1669                         }
1670                     }
1671                 }
1672             } break;
1673             case UPDATE_HTTP_PROXY_MSG: {
1674                 ProxyInfo proxy = (ProxyInfo)msg.obj;
1675                 String host = "";
1676                 String port = "";
1677                 String exclList = "";
1678                 Uri pacFileUrl = Uri.EMPTY;
1679                 if (proxy != null) {
1680                     host = proxy.getHost();
1681                     port = Integer.toString(proxy.getPort());
1682                     exclList = proxy.getExclusionListAsString();
1683                     pacFileUrl = proxy.getPacFileUrl();
1684                 }
1685                 synchronized (ActivityManagerService.this) {
1686                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1687                         ProcessRecord r = mLruProcesses.get(i);
1688                         if (r.thread != null) {
1689                             try {
1690                                 r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1691                             } catch (RemoteException ex) {
1692                                 Slog.w(TAG, "Failed to update http proxy for: " +
1693                                         r.info.processName);
1694                             }
1695                         }
1696                     }
1697                 }
1698             } break;
1699             case PROC_START_TIMEOUT_MSG: {
1700                 if (mDidDexOpt) {
1701                     mDidDexOpt = false;
1702                     Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1703                     nmsg.obj = msg.obj;
1704                     mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1705                     return;
1706                 }
1707                 ProcessRecord app = (ProcessRecord)msg.obj;
1708                 synchronized (ActivityManagerService.this) {
1709                     processStartTimedOutLocked(app);
1710                 }
1711             } break;
1712             case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: {
1713                 ProcessRecord app = (ProcessRecord)msg.obj;
1714                 synchronized (ActivityManagerService.this) {
1715                     processContentProviderPublishTimedOutLocked(app);
1716                 }
1717             } break;
1718             case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1719                 synchronized (ActivityManagerService.this) {
1720                     mStackSupervisor.doPendingActivityLaunchesLocked(true);
1721                 }
1722             } break;
1723             case KILL_APPLICATION_MSG: {
1724                 synchronized (ActivityManagerService.this) {
1725                     int appid = msg.arg1;
1726                     boolean restart = (msg.arg2 == 1);
1727                     Bundle bundle = (Bundle)msg.obj;
1728                     String pkg = bundle.getString("pkg");
1729                     String reason = bundle.getString("reason");
1730                     forceStopPackageLocked(pkg, appid, restart, false, true, false,
1731                             false, UserHandle.USER_ALL, reason);
1732                 }
1733             } break;
1734             case FINALIZE_PENDING_INTENT_MSG: {
1735                 ((PendingIntentRecord)msg.obj).completeFinalize();
1736             } break;
1737             case POST_HEAVY_NOTIFICATION_MSG: {
1738                 INotificationManager inm = NotificationManager.getService();
1739                 if (inm == null) {
1740                     return;
1741                 }
1742
1743                 ActivityRecord root = (ActivityRecord)msg.obj;
1744                 ProcessRecord process = root.app;
1745                 if (process == null) {
1746                     return;
1747                 }
1748
1749                 try {
1750                     Context context = mContext.createPackageContext(process.info.packageName, 0);
1751                     String text = mContext.getString(R.string.heavy_weight_notification,
1752                             context.getApplicationInfo().loadLabel(context.getPackageManager()));
1753                     Notification notification = new Notification.Builder(context)
1754                             .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
1755                             .setWhen(0)
1756                             .setOngoing(true)
1757                             .setTicker(text)
1758                             .setColor(mContext.getColor(
1759                                     com.android.internal.R.color.system_notification_accent_color))
1760                             .setContentTitle(text)
1761                             .setContentText(
1762                                     mContext.getText(R.string.heavy_weight_notification_detail))
1763                             .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
1764                                     root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
1765                                     new UserHandle(root.userId)))
1766                             .build();
1767                     try {
1768                         int[] outId = new int[1];
1769                         inm.enqueueNotificationWithTag("android", "android", null,
1770                                 R.string.heavy_weight_notification,
1771                                 notification, outId, root.userId);
1772                     } catch (RuntimeException e) {
1773                         Slog.w(ActivityManagerService.TAG,
1774                                 "Error showing notification for heavy-weight app", e);
1775                     } catch (RemoteException e) {
1776                     }
1777                 } catch (NameNotFoundException e) {
1778                     Slog.w(TAG, "Unable to create context for heavy notification", e);
1779                 }
1780             } break;
1781             case CANCEL_HEAVY_NOTIFICATION_MSG: {
1782                 INotificationManager inm = NotificationManager.getService();
1783                 if (inm == null) {
1784                     return;
1785                 }
1786                 try {
1787                     inm.cancelNotificationWithTag("android", null,
1788                             R.string.heavy_weight_notification,  msg.arg1);
1789                 } catch (RuntimeException e) {
1790                     Slog.w(ActivityManagerService.TAG,
1791                             "Error canceling notification for service", e);
1792                 } catch (RemoteException e) {
1793                 }
1794             } break;
1795             case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1796                 synchronized (ActivityManagerService.this) {
1797                     checkExcessivePowerUsageLocked(true);
1798                     removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1799                     Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1800                     sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1801                 }
1802             } break;
1803             case REPORT_MEM_USAGE_MSG: {
1804                 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1805                 Thread thread = new Thread() {
1806                     @Override public void run() {
1807                         reportMemUsage(memInfos);
1808                     }
1809                 };
1810                 thread.start();
1811                 break;
1812             }
1813             case REPORT_USER_SWITCH_MSG: {
1814                 dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1815                 break;
1816             }
1817             case CONTINUE_USER_SWITCH_MSG: {
1818                 continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1819                 break;
1820             }
1821             case USER_SWITCH_TIMEOUT_MSG: {
1822                 timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1823                 break;
1824             }
1825             case IMMERSIVE_MODE_LOCK_MSG: {
1826                 final boolean nextState = (msg.arg1 != 0);
1827                 if (mUpdateLock.isHeld() != nextState) {
1828                     if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
1829                             "Applying new update lock state '" + nextState
1830                             + "' for " + (ActivityRecord)msg.obj);
1831                     if (nextState) {
1832                         mUpdateLock.acquire();
1833                     } else {
1834                         mUpdateLock.release();
1835                     }
1836                 }
1837                 break;
1838             }
1839             case PERSIST_URI_GRANTS_MSG: {
1840                 writeGrantedUriPermissions();
1841                 break;
1842             }
1843             case REQUEST_ALL_PSS_MSG: {
1844                 synchronized (ActivityManagerService.this) {
1845                     requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1846                 }
1847                 break;
1848             }
1849             case START_PROFILES_MSG: {
1850                 synchronized (ActivityManagerService.this) {
1851                     startProfilesLocked();
1852                 }
1853                 break;
1854             }
1855             case UPDATE_TIME: {
1856                 synchronized (ActivityManagerService.this) {
1857                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1858                         ProcessRecord r = mLruProcesses.get(i);
1859                         if (r.thread != null) {
1860                             try {
1861                                 r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1862                             } catch (RemoteException ex) {
1863                                 Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1864                             }
1865                         }
1866                     }
1867                 }
1868                 break;
1869             }
1870             case SYSTEM_USER_START_MSG: {
1871                 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1872                         Integer.toString(msg.arg1), msg.arg1);
1873                 mSystemServiceManager.startUser(msg.arg1);
1874                 break;
1875             }
1876             case SYSTEM_USER_CURRENT_MSG: {
1877                 mBatteryStatsService.noteEvent(
1878                         BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1879                         Integer.toString(msg.arg2), msg.arg2);
1880                 mBatteryStatsService.noteEvent(
1881                         BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1882                         Integer.toString(msg.arg1), msg.arg1);
1883                 mSystemServiceManager.switchUser(msg.arg1);
1884                 break;
1885             }
1886             case ENTER_ANIMATION_COMPLETE_MSG: {
1887                 synchronized (ActivityManagerService.this) {
1888                     ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
1889                     if (r != null && r.app != null && r.app.thread != null) {
1890                         try {
1891                             r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1892                         } catch (RemoteException e) {
1893                         }
1894                     }
1895                 }
1896                 break;
1897             }
1898             case FINISH_BOOTING_MSG: {
1899                 if (msg.arg1 != 0) {
1900                     finishBooting();
1901                 }
1902                 if (msg.arg2 != 0) {
1903                     enableScreenAfterBoot();
1904                 }
1905                 break;
1906             }
1907             case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
1908                 try {
1909                     Locale l = (Locale) msg.obj;
1910                     IBinder service = ServiceManager.getService("mount");
1911                     IMountService mountService = IMountService.Stub.asInterface(service);
1912                     Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
1913                     mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
1914                 } catch (RemoteException e) {
1915                     Log.e(TAG, "Error storing locale for decryption UI", e);
1916                 }
1917                 break;
1918             }
1919             case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: {
1920                 synchronized (ActivityManagerService.this) {
1921                     int i = mTaskStackListeners.beginBroadcast();
1922                     while (i > 0) {
1923                         i--;
1924                         try {
1925                             // Make a one-way callback to the listener
1926                             mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged();
1927                         } catch (RemoteException e){
1928                             // Handled by the RemoteCallbackList
1929                         }
1930                     }
1931                     mTaskStackListeners.finishBroadcast();
1932                 }
1933                 break;
1934             }
1935             case NOTIFY_CLEARTEXT_NETWORK_MSG: {
1936                 final int uid = msg.arg1;
1937                 final byte[] firstPacket = (byte[]) msg.obj;
1938
1939                 synchronized (mPidsSelfLocked) {
1940                     for (int i = 0; i < mPidsSelfLocked.size(); i++) {
1941                         final ProcessRecord p = mPidsSelfLocked.valueAt(i);
1942                         if (p.uid == uid) {
1943                             try {
1944                                 p.thread.notifyCleartextNetwork(firstPacket);
1945                             } catch (RemoteException ignored) {
1946                             }
1947                         }
1948                     }
1949                 }
1950                 break;
1951             }
1952             case POST_DUMP_HEAP_NOTIFICATION_MSG: {
1953                 final String procName;
1954                 final int uid;
1955                 final long memLimit;
1956                 final String reportPackage;
1957                 synchronized (ActivityManagerService.this) {
1958                     procName = mMemWatchDumpProcName;
1959                     uid = mMemWatchDumpUid;
1960                     Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
1961                     if (val == null) {
1962                         val = mMemWatchProcesses.get(procName, 0);
1963                     }
1964                     if (val != null) {
1965                         memLimit = val.first;
1966                         reportPackage = val.second;
1967                     } else {
1968                         memLimit = 0;
1969                         reportPackage = null;
1970                     }
1971                 }
1972                 if (procName == null) {
1973                     return;
1974                 }
1975
1976                 if (DEBUG_PSS) Slog.d(TAG_PSS,
1977                         "Showing dump heap notification from " + procName + "/" + uid);
1978
1979                 INotificationManager inm = NotificationManager.getService();
1980                 if (inm == null) {
1981                     return;
1982                 }
1983
1984                 String text = mContext.getString(R.string.dump_heap_notification, procName);
1985
1986
1987                 Intent deleteIntent = new Intent();
1988                 deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
1989                 Intent intent = new Intent();
1990                 intent.setClassName("android", DumpHeapActivity.class.getName());
1991                 intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
1992                 intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
1993                 if (reportPackage != null) {
1994                     intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
1995                 }
1996                 int userId = UserHandle.getUserId(uid);
1997                 Notification notification = new Notification.Builder(mContext)
1998                         .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
1999                         .setWhen(0)
2000                         .setOngoing(true)
2001                         .setAutoCancel(true)
2002                         .setTicker(text)
2003                         .setColor(mContext.getColor(
2004                                 com.android.internal.R.color.system_notification_accent_color))
2005                         .setContentTitle(text)
2006                         .setContentText(
2007                                 mContext.getText(R.string.dump_heap_notification_detail))
2008                         .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2009                                 intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2010                                 new UserHandle(userId)))
2011                         .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
2012                                 deleteIntent, 0, UserHandle.OWNER))
2013                         .build();
2014
2015                 try {
2016                     int[] outId = new int[1];
2017                     inm.enqueueNotificationWithTag("android", "android", null,
2018                             R.string.dump_heap_notification,
2019                             notification, outId, userId);
2020                 } catch (RuntimeException e) {
2021                     Slog.w(ActivityManagerService.TAG,
2022                             "Error showing notification for dump heap", e);
2023                 } catch (RemoteException e) {
2024                 }
2025             } break;
2026             case DELETE_DUMPHEAP_MSG: {
2027                 revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2028                         DumpHeapActivity.JAVA_URI,
2029                         Intent.FLAG_GRANT_READ_URI_PERMISSION
2030                                 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2031                         UserHandle.myUserId());
2032                 synchronized (ActivityManagerService.this) {
2033                     mMemWatchDumpFile = null;
2034                     mMemWatchDumpProcName = null;
2035                     mMemWatchDumpPid = -1;
2036                     mMemWatchDumpUid = -1;
2037                 }
2038             } break;
2039             case FOREGROUND_PROFILE_CHANGED_MSG: {
2040                 dispatchForegroundProfileChanged(msg.arg1);
2041             } break;
2042             case REPORT_TIME_TRACKER_MSG: {
2043                 AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2044                 tracker.deliverResult(mContext);
2045             } break;
2046             case REPORT_USER_SWITCH_COMPLETE_MSG: {
2047                 dispatchUserSwitchComplete(msg.arg1);
2048             } break;
2049             case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2050                 IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2051                 try {
2052                     connection.shutdown();
2053                 } catch (RemoteException e) {
2054                     Slog.w(TAG, "Error shutting down UiAutomationConnection");
2055                 }
2056                 // Only a UiAutomation can set this flag and now that
2057                 // it is finished we make sure it is reset to its default.
2058                 mUserIsMonkey = false;
2059             } break;
2060             case APP_BOOST_DEACTIVATE_MSG : {
2061                 synchronized(ActivityManagerService.this) {
2062                     if (mIsBoosted) {
2063                         if (mBoostStartTime < (SystemClock.uptimeMillis() - APP_BOOST_TIMEOUT)) {
2064                             nativeMigrateFromBoost();
2065                             mIsBoosted = false;
2066                             mBoostStartTime = 0;
2067                         } else {
2068                             Message newmsg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
2069                             mHandler.sendMessageDelayed(newmsg, APP_BOOST_TIMEOUT);
2070                         }
2071                     }
2072                 }
2073             } break;
2074             }
2075         }
2076     };
2077
2078     static final int COLLECT_PSS_BG_MSG = 1;
2079
2080     final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2081         @Override
2082         public void handleMessage(Message msg) {
2083             switch (msg.what) {
2084             case COLLECT_PSS_BG_MSG: {
2085                 long start = SystemClock.uptimeMillis();
2086                 MemInfoReader memInfo = null;
2087                 synchronized (ActivityManagerService.this) {
2088                     if (mFullPssPending) {
2089                         mFullPssPending = false;
2090                         memInfo = new MemInfoReader();
2091                     }
2092                 }
2093                 if (memInfo != null) {
2094                     updateCpuStatsNow();
2095                     long nativeTotalPss = 0;
2096                     synchronized (mProcessCpuTracker) {
2097                         final int N = mProcessCpuTracker.countStats();
2098                         for (int j=0; j<N; j++) {
2099                             ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
2100                             if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
2101                                 // This is definitely an application process; skip it.
2102                                 continue;
2103                             }
2104                             synchronized (mPidsSelfLocked) {
2105                                 if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
2106                                     // This is one of our own processes; skip it.
2107                                     continue;
2108                                 }
2109                             }
2110                             nativeTotalPss += Debug.getPss(st.pid, null, null);
2111                         }
2112                     }
2113                     memInfo.readMemInfo();
2114                     synchronized (ActivityManagerService.this) {
2115                         if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2116                                 + (SystemClock.uptimeMillis()-start) + "ms");
2117                         final long cachedKb = memInfo.getCachedSizeKb();
2118                         final long freeKb = memInfo.getFreeSizeKb();
2119                         final long zramKb = memInfo.getZramTotalSizeKb();
2120                         final long kernelKb = memInfo.getKernelUsedSizeKb();
2121                         EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2122                                 kernelKb*1024, nativeTotalPss*1024);
2123                         mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2124                                 nativeTotalPss);
2125                     }
2126                 }
2127
2128                 int num = 0;
2129                 long[] tmp = new long[1];
2130                 do {
2131                     ProcessRecord proc;
2132                     int procState;
2133                     int pid;
2134                     long lastPssTime;
2135                     synchronized (ActivityManagerService.this) {
2136                         if (mPendingPssProcesses.size() <= 0) {
2137                             if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2138                                     "Collected PSS of " + num + " processes in "
2139                                     + (SystemClock.uptimeMillis() - start) + "ms");
2140                             mPendingPssProcesses.clear();
2141                             return;
2142                         }
2143                         proc = mPendingPssProcesses.remove(0);
2144                         procState = proc.pssProcState;
2145                         lastPssTime = proc.lastPssTime;
2146                         if (proc.thread != null && procState == proc.setProcState
2147                                 && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2148                                         < SystemClock.uptimeMillis()) {
2149                             pid = proc.pid;
2150                         } else {
2151                             proc = null;
2152                             pid = 0;
2153                         }
2154                     }
2155                     if (proc != null) {
2156                         long pss = Debug.getPss(pid, tmp, null);
2157                         synchronized (ActivityManagerService.this) {
2158                             if (pss != 0 && proc.thread != null && proc.setProcState == procState
2159                                     && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2160                                 num++;
2161                                 recordPssSampleLocked(proc, procState, pss, tmp[0],
2162                                         SystemClock.uptimeMillis());
2163                             }
2164                         }
2165                     }
2166                 } while (true);
2167             }
2168             }
2169         }
2170     };
2171
2172     public void setSystemProcess() {
2173         try {
2174             ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2175             ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2176             ServiceManager.addService("meminfo", new MemBinder(this));
2177             ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2178             ServiceManager.addService("dbinfo", new DbBinder(this));
2179             if (MONITOR_CPU_USAGE) {
2180                 ServiceManager.addService("cpuinfo", new CpuBinder(this));
2181             }
2182             ServiceManager.addService("permission", new PermissionController(this));
2183             ServiceManager.addService("processinfo", new ProcessInfoService(this));
2184
2185             ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2186                     "android", STOCK_PM_FLAGS);
2187             mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2188
2189             synchronized (this) {
2190                 ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2191                 app.persistent = true;
2192                 app.pid = MY_PID;
2193                 app.maxAdj = ProcessList.SYSTEM_ADJ;
2194                 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2195                 synchronized (mPidsSelfLocked) {
2196                     mPidsSelfLocked.put(app.pid, app);
2197                 }
2198                 updateLruProcessLocked(app, false, null);
2199                 updateOomAdjLocked();
2200             }
2201         } catch (PackageManager.NameNotFoundException e) {
2202             throw new RuntimeException(
2203                     "Unable to find android system package", e);
2204         }
2205     }
2206
2207     public void setWindowManager(WindowManagerService wm) {
2208         mWindowManager = wm;
2209         mStackSupervisor.setWindowManager(wm);
2210     }
2211
2212     public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2213         mUsageStatsService = usageStatsManager;
2214     }
2215
2216     public void startObservingNativeCrashes() {
2217         final NativeCrashListener ncl = new NativeCrashListener(this);
2218         ncl.start();
2219     }
2220
2221     public IAppOpsService getAppOpsService() {
2222         return mAppOpsService;
2223     }
2224
2225     static class MemBinder extends Binder {
2226         ActivityManagerService mActivityManagerService;
2227         MemBinder(ActivityManagerService activityManagerService) {
2228             mActivityManagerService = activityManagerService;
2229         }
2230
2231         @Override
2232         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2233             if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2234                     != PackageManager.PERMISSION_GRANTED) {
2235                 pw.println("Permission Denial: can't dump meminfo from from pid="
2236                         + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2237                         + " without permission " + android.Manifest.permission.DUMP);
2238                 return;
2239             }
2240
2241             mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2242         }
2243     }
2244
2245     static class GraphicsBinder extends Binder {
2246         ActivityManagerService mActivityManagerService;
2247         GraphicsBinder(ActivityManagerService activityManagerService) {
2248             mActivityManagerService = activityManagerService;
2249         }
2250
2251         @Override
2252         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2253             if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2254                     != PackageManager.PERMISSION_GRANTED) {
2255                 pw.println("Permission Denial: can't dump gfxinfo from from pid="
2256                         + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2257                         + " without permission " + android.Manifest.permission.DUMP);
2258                 return;
2259             }
2260
2261             mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2262         }
2263     }
2264
2265     static class DbBinder extends Binder {
2266         ActivityManagerService mActivityManagerService;
2267         DbBinder(ActivityManagerService activityManagerService) {
2268             mActivityManagerService = activityManagerService;
2269         }
2270
2271         @Override
2272         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2273             if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2274                     != PackageManager.PERMISSION_GRANTED) {
2275                 pw.println("Permission Denial: can't dump dbinfo from from pid="
2276                         + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2277                         + " without permission " + android.Manifest.permission.DUMP);
2278                 return;
2279             }
2280
2281             mActivityManagerService.dumpDbInfo(fd, pw, args);
2282         }
2283     }
2284
2285     static class CpuBinder extends Binder {
2286         ActivityManagerService mActivityManagerService;
2287         CpuBinder(ActivityManagerService activityManagerService) {
2288             mActivityManagerService = activityManagerService;
2289         }
2290
2291         @Override
2292         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2293             if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2294                     != PackageManager.PERMISSION_GRANTED) {
2295                 pw.println("Permission Denial: can't dump cpuinfo from from pid="
2296                         + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2297                         + " without permission " + android.Manifest.permission.DUMP);
2298                 return;
2299             }
2300
2301             synchronized (mActivityManagerService.mProcessCpuTracker) {
2302                 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2303                 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2304                         SystemClock.uptimeMillis()));
2305             }
2306         }
2307     }
2308
2309     public static final class Lifecycle extends SystemService {
2310         private final ActivityManagerService mService;
2311
2312         public Lifecycle(Context context) {
2313             super(context);
2314             mService = new ActivityManagerService(context);
2315         }
2316
2317         @Override
2318         public void onStart() {
2319             mService.start();
2320         }
2321
2322         public ActivityManagerService getService() {
2323             return mService;
2324         }
2325     }
2326
2327     // Note: This method is invoked on the main thread but may need to attach various
2328     // handlers to other threads.  So take care to be explicit about the looper.
2329     public ActivityManagerService(Context systemContext) {
2330         mContext = systemContext;
2331         mFactoryTest = FactoryTest.getMode();
2332         mSystemThread = ActivityThread.currentActivityThread();
2333
2334         Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2335
2336         mHandlerThread = new ServiceThread(TAG,
2337                 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2338         mHandlerThread.start();
2339         mHandler = new MainHandler(mHandlerThread.getLooper());
2340         mUiHandler = new UiHandler();
2341
2342         mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2343                 "foreground", BROADCAST_FG_TIMEOUT, false);
2344         mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2345                 "background", BROADCAST_BG_TIMEOUT, true);
2346         mBroadcastQueues[0] = mFgBroadcastQueue;
2347         mBroadcastQueues[1] = mBgBroadcastQueue;
2348
2349         mServices = new ActiveServices(this);
2350         mProviderMap = new ProviderMap(this);
2351
2352         // TODO: Move creation of battery stats service outside of activity manager service.
2353         File dataDir = Environment.getDataDirectory();
2354         File systemDir = new File(dataDir, "system");
2355         systemDir.mkdirs();
2356         mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2357         mBatteryStatsService.getActiveStatistics().readLocked();
2358         mBatteryStatsService.scheduleWriteToDisk();
2359         mOnBattery = DEBUG_POWER ? true
2360                 : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2361         mBatteryStatsService.getActiveStatistics().setCallback(this);
2362
2363         mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2364
2365         mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2366
2367         mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2368
2369         // User 0 is the first and only user that runs at boot.
2370         mStartedUsers.put(UserHandle.USER_OWNER, new UserState(UserHandle.OWNER, true));
2371         mUserLru.add(UserHandle.USER_OWNER);
2372         updateStartedUserArrayLocked();
2373
2374         GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2375             ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2376
2377         mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2378
2379         mConfiguration.setToDefaults();
2380         mConfiguration.setLocale(Locale.getDefault());
2381
2382         mConfigurationSeq = mConfiguration.seq = 1;
2383         mProcessCpuTracker.init();
2384
2385         mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2386         mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2387         mRecentTasks = new RecentTasks(this);
2388         mStackSupervisor = new ActivityStackSupervisor(this, mRecentTasks);
2389         mTaskPersister = new TaskPersister(systemDir, mStackSupervisor, mRecentTasks);
2390
2391         mProcessCpuThread = new Thread("CpuTracker") {
2392             @Override
2393             public void run() {
2394                 while (true) {
2395                     try {
2396                         try {
2397                             synchronized(this) {
2398                                 final long now = SystemClock.uptimeMillis();
2399                                 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2400                                 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2401                                 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2402                                 //        + ", write delay=" + nextWriteDelay);
2403                                 if (nextWriteDelay < nextCpuDelay) {
2404                                     nextCpuDelay = nextWriteDelay;
2405                                 }
2406                                 if (nextCpuDelay > 0) {
2407                                     mProcessCpuMutexFree.set(true);
2408                                     this.wait(nextCpuDelay);
2409                                 }
2410                             }
2411                         } catch (InterruptedException e) {
2412                         }
2413                         updateCpuStatsNow();
2414                     } catch (Exception e) {
2415                         Slog.e(TAG, "Unexpected exception collecting process stats", e);
2416                     }
2417                 }
2418             }
2419         };
2420
2421         Watchdog.getInstance().addMonitor(this);
2422         Watchdog.getInstance().addThread(mHandler);
2423     }
2424
2425     public void setSystemServiceManager(SystemServiceManager mgr) {
2426         mSystemServiceManager = mgr;
2427     }
2428
2429     public void setInstaller(Installer installer) {
2430         mInstaller = installer;
2431     }
2432
2433     private void start() {
2434         Process.removeAllProcessGroups();
2435         mProcessCpuThread.start();
2436
2437         mBatteryStatsService.publish(mContext);
2438         mAppOpsService.publish(mContext);
2439         Slog.d("AppOps", "AppOpsService published");
2440         LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2441     }
2442
2443     public void initPowerManagement() {
2444         mStackSupervisor.initPowerManagement();
2445         mBatteryStatsService.initPowerManagement();
2446         mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2447         PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2448         mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2449         mVoiceWakeLock.setReferenceCounted(false);
2450     }
2451
2452     @Override
2453     public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2454             throws RemoteException {
2455         if (code == SYSPROPS_TRANSACTION) {
2456             // We need to tell all apps about the system property change.
2457             ArrayList<IBinder> procs = new ArrayList<IBinder>();
2458             synchronized(this) {
2459                 final int NP = mProcessNames.getMap().size();
2460                 for (int ip=0; ip<NP; ip++) {
2461                     SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2462                     final int NA = apps.size();
2463                     for (int ia=0; ia<NA; ia++) {
2464                         ProcessRecord app = apps.valueAt(ia);
2465                         if (app.thread != null) {
2466                             procs.add(app.thread.asBinder());
2467                         }
2468                     }
2469                 }
2470             }
2471
2472             int N = procs.size();
2473             for (int i=0; i<N; i++) {
2474                 Parcel data2 = Parcel.obtain();
2475                 try {
2476                     procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2477                 } catch (RemoteException e) {
2478                 }
2479                 data2.recycle();
2480             }
2481         }
2482         try {
2483             return super.onTransact(code, data, reply, flags);
2484         } catch (RuntimeException e) {
2485             // The activity manager only throws security exceptions, so let's
2486             // log all others.
2487             if (!(e instanceof SecurityException)) {
2488                 Slog.wtf(TAG, "Activity Manager Crash", e);
2489             }
2490             throw e;
2491         }
2492     }
2493
2494     void updateCpuStats() {
2495         final long now = SystemClock.uptimeMillis();
2496         if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2497             return;
2498         }
2499         if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2500             synchronized (mProcessCpuThread) {
2501                 mProcessCpuThread.notify();
2502             }
2503         }
2504     }
2505
2506     void updateCpuStatsNow() {
2507         synchronized (mProcessCpuTracker) {
2508             mProcessCpuMutexFree.set(false);
2509             final long now = SystemClock.uptimeMillis();
2510             boolean haveNewCpuStats = false;
2511
2512             if (MONITOR_CPU_USAGE &&
2513                     mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2514                 mLastCpuTime.set(now);
2515                 mProcessCpuTracker.update();
2516                 if (mProcessCpuTracker.hasGoodLastStats()) {
2517                     haveNewCpuStats = true;
2518                     //Slog.i(TAG, mProcessCpu.printCurrentState());
2519                     //Slog.i(TAG, "Total CPU usage: "
2520                     //        + mProcessCpu.getTotalCpuPercent() + "%");
2521
2522                     // Slog the cpu usage if the property is set.
2523                     if ("true".equals(SystemProperties.get("events.cpu"))) {
2524                         int user = mProcessCpuTracker.getLastUserTime();
2525                         int system = mProcessCpuTracker.getLastSystemTime();
2526                         int iowait = mProcessCpuTracker.getLastIoWaitTime();
2527                         int irq = mProcessCpuTracker.getLastIrqTime();
2528                         int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2529                         int idle = mProcessCpuTracker.getLastIdleTime();
2530
2531                         int total = user + system + iowait + irq + softIrq + idle;
2532                         if (total == 0) total = 1;
2533
2534                         EventLog.writeEvent(EventLogTags.CPU,
2535                                 ((user+system+iowait+irq+softIrq) * 100) / total,
2536                                 (user * 100) / total,
2537                                 (system * 100) / total,
2538                                 (iowait * 100) / total,
2539                                 (irq * 100) / total,
2540                                 (softIrq * 100) / total);
2541                     }
2542                 }
2543             }
2544
2545             final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2546             synchronized(bstats) {
2547                 synchronized(mPidsSelfLocked) {
2548                     if (haveNewCpuStats) {
2549                         if (bstats.startAddingCpuLocked()) {
2550                             int totalUTime = 0;
2551                             int totalSTime = 0;
2552                             final int N = mProcessCpuTracker.countStats();
2553                             for (int i=0; i<N; i++) {
2554                                 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2555                                 if (!st.working) {
2556                                     continue;
2557                                 }
2558                                 ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2559                                 totalUTime += st.rel_utime;
2560                                 totalSTime += st.rel_stime;
2561                                 if (pr != null) {
2562                                     BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2563                                     if (ps == null || !ps.isActive()) {
2564                                         pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2565                                                 pr.info.uid, pr.processName);
2566                                     }
2567                                     ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2568                                     pr.curCpuTime += st.rel_utime + st.rel_stime;
2569                                 } else {
2570                                     BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2571                                     if (ps == null || !ps.isActive()) {
2572                                         st.batteryStats = ps = bstats.getProcessStatsLocked(
2573                                                 bstats.mapUid(st.uid), st.name);
2574                                     }
2575                                     ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2576                                 }
2577                             }
2578                             final int userTime = mProcessCpuTracker.getLastUserTime();
2579                             final int systemTime = mProcessCpuTracker.getLastSystemTime();
2580                             final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
2581                             final int irqTime = mProcessCpuTracker.getLastIrqTime();
2582                             final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
2583                             final int idleTime = mProcessCpuTracker.getLastIdleTime();
2584                             bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
2585                                     systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
2586                         }
2587                     }
2588                 }
2589
2590                 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2591                     mLastWriteTime = now;
2592                     mBatteryStatsService.scheduleWriteToDisk();
2593                 }
2594             }
2595         }
2596     }
2597
2598     @Override
2599     public void batteryNeedsCpuUpdate() {
2600         updateCpuStatsNow();
2601     }
2602
2603     @Override
2604     public void batteryPowerChanged(boolean onBattery) {
2605         // When plugging in, update the CPU stats first before changing
2606         // the plug state.
2607         updateCpuStatsNow();
2608         synchronized (this) {
2609             synchronized(mPidsSelfLocked) {
2610                 mOnBattery = DEBUG_POWER ? true : onBattery;
2611             }
2612         }
2613     }
2614
2615     @Override
2616     public void batterySendBroadcast(Intent intent) {
2617         broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
2618                 AppOpsManager.OP_NONE, null, false, false,
2619                 -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
2620     }
2621
2622     /**
2623      * Initialize the application bind args. These are passed to each
2624      * process when the bindApplication() IPC is sent to the process. They're
2625      * lazily setup to make sure the services are running when they're asked for.
2626      */
2627     private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2628         if (mAppBindArgs == null) {
2629             mAppBindArgs = new HashMap<>();
2630
2631             // Isolated processes won't get this optimization, so that we don't
2632             // violate the rules about which services they have access to.
2633             if (!isolated) {
2634                 // Setup the application init args
2635                 mAppBindArgs.put("package", ServiceManager.getService("package"));
2636                 mAppBindArgs.put("window", ServiceManager.getService("window"));
2637                 mAppBindArgs.put(Context.ALARM_SERVICE,
2638                         ServiceManager.getService(Context.ALARM_SERVICE));
2639             }
2640         }
2641         return mAppBindArgs;
2642     }
2643
2644     final void setFocusedActivityLocked(ActivityRecord r, String reason) {
2645         if (r != null && mFocusedActivity != r) {
2646             if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: r=" + r);
2647             ActivityRecord last = mFocusedActivity;
2648             mFocusedActivity = r;
2649             if (r.task.taskType != ActivityRecord.HOME_ACTIVITY_TYPE
2650                     && r.task.taskType != ActivityRecord.RECENTS_ACTIVITY_TYPE) {
2651                 if (mCurAppTimeTracker != r.appTimeTracker) {
2652                     // We are switching app tracking.  Complete the current one.
2653                     if (mCurAppTimeTracker != null) {
2654                         mCurAppTimeTracker.stop();
2655                         mHandler.obtainMessage(REPORT_TIME_TRACKER_MSG,
2656                                 mCurAppTimeTracker).sendToTarget();
2657                         mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
2658                         mCurAppTimeTracker = null;
2659                     }
2660                     if (r.appTimeTracker != null) {
2661                         mCurAppTimeTracker = r.appTimeTracker;
2662                         startTimeTrackingFocusedActivityLocked();
2663                     }
2664                 } else {
2665                     startTimeTrackingFocusedActivityLocked();
2666                 }
2667             } else {
2668                 r.appTimeTracker = null;
2669             }
2670             if (r.task != null && r.task.voiceInteractor != null) {
2671                 startRunningVoiceLocked(r.task.voiceSession, r.info.applicationInfo.uid);
2672             } else {
2673                 finishRunningVoiceLocked();
2674                 if (last != null && last.task.voiceSession != null) {
2675                     // We had been in a voice interaction session, but now focused has
2676                     // move to something different.  Just finish the session, we can't
2677                     // return to it and retain the proper state and synchronization with
2678                     // the voice interaction service.
2679                     finishVoiceTask(last.task.voiceSession);
2680                 }
2681             }
2682             if (mStackSupervisor.setFocusedStack(r, reason + " setFocusedActivity")) {
2683                 mWindowManager.setFocusedApp(r.appToken, true);
2684             }
2685             applyUpdateLockStateLocked(r);
2686             if (mFocusedActivity.userId != mLastFocusedUserId) {
2687                 mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2688                 mHandler.sendMessage(mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG,
2689                         mFocusedActivity.userId, 0));
2690                 mLastFocusedUserId = mFocusedActivity.userId;
2691             }
2692         }
2693         EventLog.writeEvent(EventLogTags.AM_FOCUSED_ACTIVITY,
2694                 mFocusedActivity == null ? -1 : mFocusedActivity.userId,
2695                 mFocusedActivity == null ? "NULL" : mFocusedActivity.shortComponentName);
2696     }
2697
2698     final void clearFocusedActivity(ActivityRecord r) {
2699         if (mFocusedActivity == r) {
2700             ActivityStack stack = mStackSupervisor.getFocusedStack();
2701             if (stack != null) {
2702                 ActivityRecord top = stack.topActivity();
2703                 if (top != null && top.userId != mLastFocusedUserId) {
2704                     mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2705                     mHandler.sendMessage(mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG,
2706                                     top.userId, 0));
2707                     mLastFocusedUserId = top.userId;
2708                 }
2709             }
2710             mFocusedActivity = null;
2711             EventLog.writeEvent(EventLogTags.AM_FOCUSED_ACTIVITY, -1, "NULL");
2712         }
2713     }
2714
2715     @Override
2716     public void setFocusedStack(int stackId) {
2717         if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
2718         synchronized (ActivityManagerService.this) {
2719             ActivityStack stack = mStackSupervisor.getStack(stackId);
2720             if (stack != null) {
2721                 ActivityRecord r = stack.topRunningActivityLocked(null);
2722                 if (r != null) {
2723                     setFocusedActivityLocked(r, "setFocusedStack");
2724                     mStackSupervisor.resumeTopActivitiesLocked(stack, null, null);
2725                 }
2726             }
2727         }
2728     }
2729
2730     /** Sets the task stack listener that gets callbacks when a task stack changes. */
2731     @Override
2732     public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
2733         synchronized (ActivityManagerService.this) {
2734             if (listener != null) {
2735                 mTaskStackListeners.register(listener);
2736             }
2737         }
2738     }
2739
2740     @Override
2741     public void notifyActivityDrawn(IBinder token) {
2742         if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
2743         synchronized (this) {
2744             ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
2745             if (r != null) {
2746                 r.task.stack.notifyActivityDrawnLocked(r);
2747             }
2748         }
2749     }
2750
2751     final void applyUpdateLockStateLocked(ActivityRecord r) {
2752         // Modifications to the UpdateLock state are done on our handler, outside
2753         // the activity manager's locks.  The new state is determined based on the
2754         // state *now* of the relevant activity record.  The object is passed to
2755         // the handler solely for logging detail, not to be consulted/modified.
2756         final boolean nextState = r != null && r.immersive;
2757         mHandler.sendMessage(
2758                 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2759     }
2760
2761     final void showAskCompatModeDialogLocked(ActivityRecord r) {
2762         Message msg = Message.obtain();
2763         msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2764         msg.obj = r.task.askedCompatMode ? null : r;
2765         mUiHandler.sendMessage(msg);
2766     }
2767
2768     private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2769             String what, Object obj, ProcessRecord srcApp) {
2770         app.lastActivityTime = now;
2771
2772         if (app.activities.size() > 0) {
2773             // Don't want to touch dependent processes that are hosting activities.
2774             return index;
2775         }
2776
2777         int lrui = mLruProcesses.lastIndexOf(app);
2778         if (lrui < 0) {
2779             Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2780                     + what + " " + obj + " from " + srcApp);
2781             return index;
2782         }
2783
2784         if (lrui >= index) {
2785             // Don't want to cause this to move dependent processes *back* in the
2786             // list as if they were less frequently used.
2787             return index;
2788         }
2789
2790         if (lrui >= mLruProcessActivityStart) {
2791             // Don't want to touch dependent processes that are hosting activities.
2792             return index;
2793         }
2794
2795         mLruProcesses.remove(lrui);
2796         if (index > 0) {
2797             index--;
2798         }
2799         if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
2800                 + " in LRU list: " + app);
2801         mLruProcesses.add(index, app);
2802         return index;
2803     }
2804
2805     private static void killProcessGroup(int uid, int pid) {
2806         Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
2807         Process.killProcessGroup(uid, pid);
2808         Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
2809     }
2810
2811     final void removeLruProcessLocked(ProcessRecord app) {
2812         int lrui = mLruProcesses.lastIndexOf(app);
2813         if (lrui >= 0) {
2814             if (!app.killed) {
2815                 Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
2816                 Process.killProcessQuiet(app.pid);
2817                 killProcessGroup(app.info.uid, app.pid);
2818             }
2819             if (lrui <= mLruProcessActivityStart) {
2820                 mLruProcessActivityStart--;
2821             }
2822             if (lrui <= mLruProcessServiceStart) {
2823                 mLruProcessServiceStart--;
2824             }
2825             mLruProcesses.remove(lrui);
2826         }
2827     }
2828
2829     final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2830             ProcessRecord client) {
2831         final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2832                 || app.treatLikeActivity;
2833         final boolean hasService = false; // not impl yet. app.services.size() > 0;
2834         if (!activityChange && hasActivity) {
2835             // The process has activities, so we are only allowing activity-based adjustments
2836             // to move it.  It should be kept in the front of the list with other
2837             // processes that have activities, and we don't want those to change their
2838             // order except due to activity operations.
2839             return;
2840         }
2841
2842         mLruSeq++;
2843         final long now = SystemClock.uptimeMillis();
2844         app.lastActivityTime = now;
2845
2846         // First a quick reject: if the app is already at the position we will
2847         // put it, then there is nothing to do.
2848         if (hasActivity) {
2849             final int N = mLruProcesses.size();
2850             if (N > 0 && mLruProcesses.get(N-1) == app) {
2851                 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
2852                 return;
2853             }
2854         } else {
2855             if (mLruProcessServiceStart > 0
2856                     && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2857                 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
2858                 return;
2859             }
2860         }
2861
2862         int lrui = mLruProcesses.lastIndexOf(app);
2863
2864         if (app.persistent && lrui >= 0) {
2865             // We don't care about the position of persistent processes, as long as
2866             // they are in the list.
2867             if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
2868             return;
2869         }
2870
2871         /* In progress: compute new position first, so we can avoid doing work
2872            if the process is not actually going to move.  Not yet working.
2873         int addIndex;
2874         int nextIndex;
2875         boolean inActivity = false, inService = false;
2876         if (hasActivity) {
2877             // Process has activities, put it at the very tipsy-top.
2878             addIndex = mLruProcesses.size();
2879             nextIndex = mLruProcessServiceStart;
2880             inActivity = true;
2881         } else if (hasService) {
2882             // Process has services, put it at the top of the service list.
2883             addIndex = mLruProcessActivityStart;
2884             nextIndex = mLruProcessServiceStart;
2885             inActivity = true;
2886             inService = true;
2887         } else  {
2888             // Process not otherwise of interest, it goes to the top of the non-service area.
2889             addIndex = mLruProcessServiceStart;
2890             if (client != null) {
2891                 int clientIndex = mLruProcesses.lastIndexOf(client);
2892                 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2893                         + app);
2894                 if (clientIndex >= 0 && addIndex > clientIndex) {
2895                     addIndex = clientIndex;
2896                 }
2897             }
2898             nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2899         }
2900
2901         Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2902                 + mLruProcessActivityStart + "): " + app);
2903         */
2904
2905         if (lrui >= 0) {
2906             if (lrui < mLruProcessActivityStart) {
2907                 mLruProcessActivityStart--;
2908             }
2909             if (lrui < mLruProcessServiceStart) {
2910                 mLruProcessServiceStart--;
2911             }
2912             /*
2913             if (addIndex > lrui) {
2914                 addIndex--;
2915             }
2916             if (nextIndex > lrui) {
2917                 nextIndex--;
2918             }
2919             */
2920             mLruProcesses.remove(lrui);
2921         }
2922
2923         /*
2924         mLruProcesses.add(addIndex, app);
2925         if (inActivity) {
2926             mLruProcessActivityStart++;
2927         }
2928         if (inService) {
2929             mLruProcessActivityStart++;
2930         }
2931         */
2932
2933         int nextIndex;
2934         if (hasActivity) {
2935             final int N = mLruProcesses.size();
2936             if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
2937                 // Process doesn't have activities, but has clients with
2938                 // activities...  move it up, but one below the top (the top
2939                 // should always have a real activity).
2940                 if (DEBUG_LRU) Slog.d(TAG_LRU,
2941                         "Adding to second-top of LRU activity list: " + app);
2942                 mLruProcesses.add(N - 1, app);
2943                 // To keep it from spamming the LRU list (by making a bunch of clients),
2944                 // we will push down any other entries owned by the app.
2945                 final int uid = app.info.uid;
2946                 for (int i = N - 2; i > mLruProcessActivityStart; i--) {
2947                     ProcessRecord subProc = mLruProcesses.get(i);
2948                     if (subProc.info.uid == uid) {
2949                         // We want to push this one down the list.  If the process after
2950                         // it is for the same uid, however, don't do so, because we don't
2951                         // want them internally to be re-ordered.
2952                         if (mLruProcesses.get(i - 1).info.uid != uid) {
2953                             if (DEBUG_LRU) Slog.d(TAG_LRU,
2954                                     "Pushing uid " + uid + " swapping at " + i + ": "
2955                                     + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
2956                             ProcessRecord tmp = mLruProcesses.get(i);
2957                             mLruProcesses.set(i, mLruProcesses.get(i - 1));
2958                             mLruProcesses.set(i - 1, tmp);
2959                             i--;
2960                         }
2961                     } else {
2962                         // A gap, we can stop here.
2963                         break;
2964                     }
2965                 }
2966             } else {
2967                 // Process has activities, put it at the very tipsy-top.
2968                 if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
2969                 mLruProcesses.add(app);
2970             }
2971             nextIndex = mLruProcessServiceStart;
2972         } else if (hasService) {
2973             // Process has services, put it at the top of the service list.
2974             if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
2975             mLruProcesses.add(mLruProcessActivityStart, app);
2976             nextIndex = mLruProcessServiceStart;
2977             mLruProcessActivityStart++;
2978         } else  {
2979             // Process not otherwise of interest, it goes to the top of the non-service area.
2980             int index = mLruProcessServiceStart;
2981             if (client != null) {
2982                 // If there is a client, don't allow the process to be moved up higher
2983                 // in the list than that client.
2984                 int clientIndex = mLruProcesses.lastIndexOf(client);
2985                 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
2986                         + " when updating " + app);
2987                 if (clientIndex <= lrui) {
2988                     // Don't allow the client index restriction to push it down farther in the
2989                     // list than it already is.
2990                     clientIndex = lrui;
2991                 }
2992                 if (clientIndex >= 0 && index > clientIndex) {
2993                     index = clientIndex;
2994                 }
2995             }
2996             if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
2997             mLruProcesses.add(index, app);
2998             nextIndex = index-1;
2999             mLruProcessActivityStart++;
3000             mLruProcessServiceStart++;
3001         }
3002
3003         // If the app is currently using a content provider or service,
3004         // bump those processes as well.
3005         for (int j=app.connections.size()-1; j>=0; j--) {
3006             ConnectionRecord cr = app.connections.valueAt(j);
3007             if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
3008                     && cr.binding.service.app != null
3009                     && cr.binding.service.app.lruSeq != mLruSeq
3010                     && !cr.binding.service.app.persistent) {
3011                 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
3012                         "service connection", cr, app);
3013             }
3014         }
3015         for (int j=app.conProviders.size()-1; j>=0; j--) {
3016             ContentProviderRecord cpr = app.conProviders.get(j).provider;
3017             if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
3018                 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
3019                         "provider reference", cpr, app);
3020             }
3021         }
3022     }
3023
3024     final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
3025         if (uid == Process.SYSTEM_UID) {
3026             // The system gets to run in any process.  If there are multiple
3027             // processes with the same uid, just pick the first (this
3028             // should never happen).
3029             SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
3030             if (procs == null) return null;
3031             final int procCount = procs.size();
3032             for (int i = 0; i < procCount; i++) {
3033                 final int procUid = procs.keyAt(i);
3034                 if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
3035                     // Don't use an app process or different user process for system component.
3036                     continue;
3037                 }
3038                 return procs.valueAt(i);
3039             }
3040         }
3041         ProcessRecord proc = mProcessNames.get(processName, uid);
3042         if (false && proc != null && !keepIfLarge
3043                 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3044                 && proc.lastCachedPss >= 4000) {
3045             // Turn this condition on to cause killing to happen regularly, for testing.
3046             if (proc.baseProcessTracker != null) {
3047                 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3048             }
3049             proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3050         } else if (proc != null && !keepIfLarge
3051                 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3052                 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3053             if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3054             if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3055                 if (proc.baseProcessTracker != null) {
3056                     proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3057                 }
3058                 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3059             }
3060         }
3061         return proc;
3062     }
3063
3064     void ensurePackageDexOpt(String packageName) {
3065         IPackageManager pm = AppGlobals.getPackageManager();
3066         try {
3067             if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) {
3068                 mDidDexOpt = true;
3069             }
3070         } catch (RemoteException e) {
3071         }
3072     }
3073
3074     boolean isNextTransitionForward() {
3075         int transit = mWindowManager.getPendingAppTransition();
3076         return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
3077                 || transit == AppTransition.TRANSIT_TASK_OPEN
3078                 || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
3079     }
3080
3081     int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3082             String processName, String abiOverride, int uid, Runnable crashHandler) {
3083         synchronized(this) {
3084             ApplicationInfo info = new ApplicationInfo();
3085             // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3086             // For isolated processes, the former contains the parent's uid and the latter the
3087             // actual uid of the isolated process.
3088             // In the special case introduced by this method (which is, starting an isolated
3089             // process directly from the SystemServer without an actual parent app process) the
3090             // closest thing to a parent's uid is SYSTEM_UID.
3091             // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3092             // the |isolated| logic in the ProcessRecord constructor.
3093             info.uid = Process.SYSTEM_UID;
3094             info.processName = processName;
3095             info.className = entryPoint;
3096             info.packageName = "android";
3097             ProcessRecord proc = startProcessLocked(processName, info /* info */,
3098                     false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
3099                     null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3100                     uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3101                     crashHandler);
3102             return proc != null ? proc.pid : 0;
3103         }
3104     }
3105
3106     final ProcessRecord startProcessLocked(String processName,
3107             ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3108             String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3109             boolean isolated, boolean keepIfLarge) {
3110         return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3111                 hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3112                 null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3113                 null /* crashHandler */);
3114     }
3115
3116     final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3117             boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3118             boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3119             String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3120         long startTime = SystemClock.elapsedRealtime();
3121         ProcessRecord app;
3122         if (!isolated) {
3123             app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3124             checkTime(startTime, "startProcess: after getProcessRecord");
3125
3126             if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3127                 // If we are in the background, then check to see if this process
3128                 // is bad.  If so, we will just silently fail.
3129                 if (mBadProcesses.get(info.processName, info.uid) != null) {
3130                     if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3131                             + "/" + info.processName);
3132                     return null;
3133                 }
3134             } else {
3135                 // When the user is explicitly starting a process, then clear its
3136                 // crash count so that we won't make it bad until they see at
3137                 // least one crash dialog again, and make the process good again
3138                 // if it had been bad.
3139                 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3140                         + "/" + info.processName);
3141                 mProcessCrashTimes.remove(info.processName, info.uid);
3142                 if (mBadProcesses.get(info.processName, info.uid) != null) {
3143                     EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3144                             UserHandle.getUserId(info.uid), info.uid,
3145                             info.processName);
3146                     mBadProcesses.remove(info.processName, info.uid);
3147                     if (app != null) {
3148                         app.bad = false;
3149                     }
3150                 }
3151             }
3152         } else {
3153             // If this is an isolated process, it can't re-use an existing process.
3154             app = null;
3155         }
3156
3157         // app launch boost for big.little configurations
3158         // use cpusets to migrate freshly launched tasks to big cores
3159         synchronized(ActivityManagerService.this) {
3160             nativeMigrateToBoost();
3161             mIsBoosted = true;
3162             mBoostStartTime = SystemClock.uptimeMillis();
3163             Message msg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
3164             mHandler.sendMessageDelayed(msg, APP_BOOST_MESSAGE_DELAY);
3165         }
3166
3167         // We don't have to do anything more if:
3168         // (1) There is an existing application record; and
3169         // (2) The caller doesn't think it is dead, OR there is no thread
3170         //     object attached to it so we know it couldn't have crashed; and
3171         // (3) There is a pid assigned to it, so it is either starting or
3172         //     already running.
3173         if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3174                 + " app=" + app + " knownToBeDead=" + knownToBeDead
3175                 + " thread=" + (app != null ? app.thread : null)
3176                 + " pid=" + (app != null ? app.pid : -1));
3177         if (app != null && app.pid > 0) {
3178             if (!knownToBeDead || app.thread == null) {
3179                 // We already have the app running, or are waiting for it to
3180                 // come up (we have a pid but not yet its thread), so keep it.
3181                 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3182                 // If this is a new package in the process, add the package to the list
3183                 app.addPackage(info.packageName, info.versionCode, mProcessStats);
3184                 checkTime(startTime, "startProcess: done, added package to proc");
3185                 return app;
3186             }
3187
3188             // An application record is attached to a previous process,
3189             // clean it up now.
3190             if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3191             checkTime(startTime, "startProcess: bad proc running, killing");
3192             killProcessGroup(app.info.uid, app.pid);
3193             handleAppDiedLocked(app, true, true);
3194             checkTime(startTime, "startProcess: done killing old proc");
3195         }
3196
3197         String hostingNameStr = hostingName != null
3198                 ? hostingName.flattenToShortString() : null;
3199
3200         if (app == null) {
3201             checkTime(startTime, "startProcess: creating new process record");
3202             app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3203             if (app == null) {
3204                 Slog.w(TAG, "Failed making new process record for "
3205                         + processName + "/" + info.uid + " isolated=" + isolated);
3206                 return null;
3207             }
3208             app.crashHandler = crashHandler;
3209             checkTime(startTime, "startProcess: done creating new process record");
3210         } else {
3211             // If this is a new package in the process, add the package to the list
3212             app.addPackage(info.packageName, info.versionCode, mProcessStats);
3213             checkTime(startTime, "startProcess: added package to existing proc");
3214         }
3215
3216         // If the system is not ready yet, then hold off on starting this
3217         // process until it is.
3218         if (!mProcessesReady
3219                 && !isAllowedWhileBooting(info)
3220                 && !allowWhileBooting) {
3221             if (!mProcessesOnHold.contains(app)) {
3222                 mProcessesOnHold.add(app);
3223             }
3224             if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3225                     "System not ready, putting on hold: " + app);
3226             checkTime(startTime, "startProcess: returning with proc on hold");
3227             return app;
3228         }
3229
3230         checkTime(startTime, "startProcess: stepping in to startProcess");
3231         startProcessLocked(
3232                 app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3233         checkTime(startTime, "startProcess: done starting proc!");
3234         return (app.pid != 0) ? app : null;
3235     }
3236
3237     boolean isAllowedWhileBooting(ApplicationInfo ai) {
3238         return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3239     }
3240
3241     private final void startProcessLocked(ProcessRecord app,
3242             String hostingType, String hostingNameStr) {
3243         startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3244                 null /* entryPoint */, null /* entryPointArgs */);
3245     }
3246
3247     private final void startProcessLocked(ProcessRecord app, String hostingType,
3248             String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3249         long startTime = SystemClock.elapsedRealtime();
3250         if (app.pid > 0 && app.pid != MY_PID) {
3251             checkTime(startTime, "startProcess: removing from pids map");
3252             synchronized (mPidsSelfLocked) {
3253                 mPidsSelfLocked.remove(app.pid);
3254                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3255             }
3256             checkTime(startTime, "startProcess: done removing from pids map");
3257             app.setPid(0);
3258         }
3259
3260         if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3261                 "startProcessLocked removing on hold: " + app);
3262         mProcessesOnHold.remove(app);
3263
3264         checkTime(startTime, "startProcess: starting to update cpu stats");
3265         updateCpuStats();
3266         checkTime(startTime, "startProcess: done updating cpu stats");
3267
3268         try {
3269             try {
3270                 if (AppGlobals.getPackageManager().isPackageFrozen(app.info.packageName)) {
3271                     // This is caught below as if we had failed to fork zygote
3272                     throw new RuntimeException("Package " + app.info.packageName + " is frozen!");
3273                 }
3274             } catch (RemoteException e) {
3275                 throw e.rethrowAsRuntimeException();
3276             }
3277
3278             int uid = app.uid;
3279             int[] gids = null;
3280             int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3281             if (!app.isolated) {
3282                 int[] permGids = null;
3283                 try {
3284                     checkTime(startTime, "startProcess: getting gids from package manager");
3285                     final IPackageManager pm = AppGlobals.getPackageManager();
3286                     permGids = pm.getPackageGids(app.info.packageName, app.userId);
3287                     MountServiceInternal mountServiceInternal = LocalServices.getService(
3288                             MountServiceInternal.class);
3289                     mountExternal = mountServiceInternal.getExternalStorageMountMode(uid,
3290                             app.info.packageName);
3291                 } catch (RemoteException e) {
3292                     throw e.rethrowAsRuntimeException();
3293                 }
3294
3295                 /*
3296                  * Add shared application and profile GIDs so applications can share some
3297                  * resources like shared libraries and access user-wide resources
3298                  */
3299                 if (ArrayUtils.isEmpty(permGids)) {
3300                     gids = new int[2];
3301                 } else {
3302                     gids = new int[permGids.length + 2];
3303                     System.arraycopy(permGids, 0, gids, 2, permGids.length);
3304                 }
3305                 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3306                 gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3307             }
3308             checkTime(startTime, "startProcess: building args");
3309             if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3310                 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3311                         && mTopComponent != null
3312                         && app.processName.equals(mTopComponent.getPackageName())) {
3313                     uid = 0;
3314                 }
3315                 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3316                         && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3317                     uid = 0;
3318                 }
3319             }
3320             int debugFlags = 0;
3321             if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3322                 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3323                 // Also turn on CheckJNI for debuggable apps. It's quite
3324                 // awkward to turn on otherwise.
3325                 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3326             }
3327             // Run the app in safe mode if its manifest requests so or the
3328             // system is booted in safe mode.
3329             if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3330                 mSafeMode == true) {
3331                 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3332             }
3333             if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3334                 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3335             }
3336             String jitDebugProperty = SystemProperties.get("debug.usejit");
3337             if ("true".equals(jitDebugProperty)) {
3338                 debugFlags |= Zygote.DEBUG_ENABLE_JIT;
3339             } else if (!"false".equals(jitDebugProperty)) {
3340                 // If we didn't force disable by setting false, defer to the dalvik vm options.
3341                 if ("true".equals(SystemProperties.get("dalvik.vm.usejit"))) {
3342                     debugFlags |= Zygote.DEBUG_ENABLE_JIT;
3343                 }
3344             }
3345             String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3346             if ("true".equals(genDebugInfoProperty)) {
3347                 debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3348             }
3349             if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3350                 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3351             }
3352             if ("1".equals(SystemProperties.get("debug.assert"))) {
3353                 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3354             }
3355
3356             String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3357             if (requiredAbi == null) {
3358                 requiredAbi = Build.SUPPORTED_ABIS[0];
3359             }
3360
3361             String instructionSet = null;
3362             if (app.info.primaryCpuAbi != null) {
3363                 instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3364             }
3365
3366             app.gids = gids;
3367             app.requiredAbi = requiredAbi;
3368             app.instructionSet = instructionSet;
3369
3370             // Start the process.  It will either succeed and return a result containing
3371             // the PID of the new process, or else throw a RuntimeException.
3372             boolean isActivityProcess = (entryPoint == null);
3373             if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3374             Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3375                     app.processName);
3376             checkTime(startTime, "startProcess: asking zygote to start proc");
3377             Process.ProcessStartResult startResult = Process.start(entryPoint,
3378                     app.processName, uid, uid, gids, debugFlags, mountExternal,
3379                     app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3380                     app.info.dataDir, entryPointArgs);
3381             checkTime(startTime, "startProcess: returned from zygote!");
3382             Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3383
3384             if (app.isolated) {
3385                 mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3386             }
3387             mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3388             checkTime(startTime, "startProcess: done updating battery stats");
3389
3390             EventLog.writeEvent(EventLogTags.AM_PROC_START,
3391                     UserHandle.getUserId(uid), startResult.pid, uid,
3392                     app.processName, hostingType,
3393                     hostingNameStr != null ? hostingNameStr : "");
3394
3395             if (app.persistent) {
3396                 Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3397             }
3398
3399             checkTime(startTime, "startProcess: building log message");
3400             StringBuilder buf = mStringBuilder;
3401             buf.setLength(0);
3402             buf.append("Start proc ");
3403             buf.append(startResult.pid);
3404             buf.append(':');
3405             buf.append(app.processName);
3406             buf.append('/');
3407             UserHandle.formatUid(buf, uid);
3408             if (!isActivityProcess) {
3409                 buf.append(" [");
3410                 buf.append(entryPoint);
3411                 buf.append("]");
3412             }
3413             buf.append(" for ");
3414             buf.append(hostingType);
3415             if (hostingNameStr != null) {
3416                 buf.append(" ");
3417                 buf.append(hostingNameStr);
3418             }
3419             Slog.i(TAG, buf.toString());
3420             app.setPid(startResult.pid);
3421             app.usingWrapper = startResult.usingWrapper;
3422             app.removed = false;
3423             app.killed = false;
3424             app.killedByAm = false;
3425             checkTime(startTime, "startProcess: starting to update pids map");
3426             synchronized (mPidsSelfLocked) {
3427                 this.mPidsSelfLocked.put(startResult.pid, app);
3428                 if (isActivityProcess) {
3429                     Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3430                     msg.obj = app;
3431                     mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3432                             ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3433                 }
3434             }
3435             checkTime(startTime, "startProcess: done updating pids map");
3436         } catch (RuntimeException e) {
3437             // XXX do better error recovery.
3438             app.setPid(0);
3439             mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3440             if (app.isolated) {
3441                 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3442             }
3443             Slog.e(TAG, "Failure starting process " + app.processName, e);
3444         }
3445     }
3446
3447     void updateUsageStats(ActivityRecord component, boolean resumed) {
3448         if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
3449                 "updateUsageStats: comp=" + component + "res=" + resumed);
3450         final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3451         if (resumed) {
3452             if (mUsageStatsService != null) {
3453                 mUsageStatsService.reportEvent(component.realActivity, component.userId,
3454                         UsageEvents.Event.MOVE_TO_FOREGROUND);
3455             }
3456             synchronized (stats) {
3457                 stats.noteActivityResumedLocked(component.app.uid);
3458             }
3459         } else {
3460             if (mUsageStatsService != null) {
3461                 mUsageStatsService.reportEvent(component.realActivity, component.userId,
3462                         UsageEvents.Event.MOVE_TO_BACKGROUND);
3463             }
3464             synchronized (stats) {
3465                 stats.noteActivityPausedLocked(component.app.uid);
3466             }
3467         }
3468     }
3469
3470     Intent getHomeIntent() {
3471         Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3472         intent.setComponent(mTopComponent);
3473         if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3474             intent.addCategory(Intent.CATEGORY_HOME);
3475         }
3476         return intent;
3477     }
3478
3479     boolean startHomeActivityLocked(int userId, String reason) {
3480         if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3481                 && mTopAction == null) {
3482             // We are running in factory test mode, but unable to find
3483             // the factory test app, so just sit around displaying the
3484             // error message and don't try to start anything.
3485             return false;
3486         }
3487         Intent intent = getHomeIntent();
3488         ActivityInfo aInfo =
3489             resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3490         if (aInfo != null) {
3491             intent.setComponent(new ComponentName(
3492                     aInfo.applicationInfo.packageName, aInfo.name));
3493             // Don't do this if the home app is currently being
3494             // instrumented.
3495             aInfo = new ActivityInfo(aInfo);
3496             aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3497             ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3498                     aInfo.applicationInfo.uid, true);
3499             if (app == null || app.instrumentationClass == null) {
3500                 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3501                 mStackSupervisor.startHomeActivity(intent, aInfo, reason);
3502             }
3503         }
3504
3505         return true;
3506     }
3507
3508     private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3509         ActivityInfo ai = null;
3510         ComponentName comp = intent.getComponent();
3511         try {
3512             if (comp != null) {
3513                 // Factory test.
3514                 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3515             } else {
3516                 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3517                         intent,
3518                         intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3519                         flags, userId);
3520
3521                 if (info != null) {
3522                     ai = info.activityInfo;
3523                 }
3524             }
3525         } catch (RemoteException e) {
3526             // ignore
3527         }
3528
3529         return ai;
3530     }
3531
3532     /**
3533      * Starts the "new version setup screen" if appropriate.
3534      */
3535     void startSetupActivityLocked() {
3536         // Only do this once per boot.
3537         if (mCheckedForSetup) {
3538             return;
3539         }
3540
3541         // We will show this screen if the current one is a different
3542         // version than the last one shown, and we are not running in
3543         // low-level factory test mode.
3544         final ContentResolver resolver = mContext.getContentResolver();
3545         if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3546                 Settings.Global.getInt(resolver,
3547                         Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3548             mCheckedForSetup = true;
3549
3550             // See if we should be showing the platform update setup UI.
3551             Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3552             List<ResolveInfo> ris = mContext.getPackageManager()
3553                     .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3554
3555             // We don't allow third party apps to replace this.
3556             ResolveInfo ri = null;
3557             for (int i=0; ris != null && i<ris.size(); i++) {
3558                 if ((ris.get(i).activityInfo.applicationInfo.flags
3559                         & ApplicationInfo.FLAG_SYSTEM) != 0) {
3560                     ri = ris.get(i);
3561                     break;
3562                 }
3563             }
3564
3565             if (ri != null) {
3566                 String vers = ri.activityInfo.metaData != null
3567                         ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3568                         : null;
3569                 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3570                     vers = ri.activityInfo.applicationInfo.metaData.getString(
3571                             Intent.METADATA_SETUP_VERSION);
3572                 }
3573                 String lastVers = Settings.Secure.getString(
3574                         resolver, Settings.Secure.LAST_SETUP_SHOWN);
3575                 if (vers != null && !vers.equals(lastVers)) {
3576                     intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3577                     intent.setComponent(new ComponentName(
3578                             ri.activityInfo.packageName, ri.activityInfo.name));
3579                     mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3580                             null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, false,
3581                             null, null, null);
3582                 }
3583             }
3584         }
3585     }
3586
3587     CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3588         return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3589     }
3590
3591     void enforceNotIsolatedCaller(String caller) {
3592         if (UserHandle.isIsolated(Binder.getCallingUid())) {
3593             throw new SecurityException("Isolated process not allowed to call " + caller);
3594         }
3595     }
3596
3597     void enforceShellRestriction(String restriction, int userHandle) {
3598         if (Binder.getCallingUid() == Process.SHELL_UID) {
3599             if (userHandle < 0
3600                     || mUserManager.hasUserRestriction(restriction, userHandle)) {
3601                 throw new SecurityException("Shell does not have permission to access user "
3602                         + userHandle);
3603             }
3604         }
3605     }
3606
3607     @Override
3608     public int getFrontActivityScreenCompatMode() {
3609         enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3610         synchronized (this) {
3611             return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3612         }
3613     }
3614
3615     @Override
3616     public void setFrontActivityScreenCompatMode(int mode) {
3617         enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3618                 "setFrontActivityScreenCompatMode");
3619         synchronized (this) {
3620             mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3621         }
3622     }
3623
3624     @Override
3625     public int getPackageScreenCompatMode(String packageName) {
3626         enforceNotIsolatedCaller("getPackageScreenCompatMode");
3627         synchronized (this) {
3628             return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3629         }
3630     }
3631
3632     @Override
3633     public void setPackageScreenCompatMode(String packageName, int mode) {
3634         enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3635                 "setPackageScreenCompatMode");
3636         synchronized (this) {
3637             mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3638         }
3639     }
3640
3641     @Override
3642     public boolean getPackageAskScreenCompat(String packageName) {
3643         enforceNotIsolatedCaller("getPackageAskScreenCompat");
3644         synchronized (this) {
3645             return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3646         }
3647     }
3648
3649     @Override
3650     public void setPackageAskScreenCompat(String packageName, boolean ask) {
3651         enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3652                 "setPackageAskScreenCompat");
3653         synchronized (this) {
3654             mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3655         }
3656     }
3657
3658     private boolean hasUsageStatsPermission(String callingPackage) {
3659         final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
3660                 Binder.getCallingUid(), callingPackage);
3661         if (mode == AppOpsManager.MODE_DEFAULT) {
3662             return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
3663                     == PackageManager.PERMISSION_GRANTED;
3664         }
3665         return mode == AppOpsManager.MODE_ALLOWED;
3666     }
3667
3668     @Override
3669     public int getPackageProcessState(String packageName, String callingPackage) {
3670         if (!hasUsageStatsPermission(callingPackage)) {
3671             enforceCallingPermission(android.Manifest.permission.GET_PACKAGE_IMPORTANCE,
3672                     "getPackageProcessState");
3673         }
3674
3675         int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
3676         synchronized (this) {
3677             for (int i=mLruProcesses.size()-1; i>=0; i--) {
3678                 final ProcessRecord proc = mLruProcesses.get(i);
3679                 if (procState == ActivityManager.PROCESS_STATE_NONEXISTENT
3680                         || procState > proc.setProcState) {
3681                     boolean found = false;
3682                     for (int j=proc.pkgList.size()-1; j>=0 && !found; j--) {
3683                         if (proc.pkgList.keyAt(j).equals(packageName)) {
3684                             procState = proc.setProcState;
3685                             found = true;
3686                         }
3687                     }
3688                     if (proc.pkgDeps != null && !found) {
3689                         for (int j=proc.pkgDeps.size()-1; j>=0; j--) {
3690                             if (proc.pkgDeps.valueAt(j).equals(packageName)) {
3691                                 procState = proc.setProcState;
3692                                 break;
3693                             }
3694                         }
3695                     }
3696                 }
3697             }
3698         }
3699         return procState;
3700     }
3701
3702     @Override
3703     public boolean setProcessMemoryTrimLevel(String process, int userId, int level) {
3704         synchronized (this) {
3705             final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
3706             if (app == null) {
3707                 return false;
3708             }
3709             if (app.trimMemoryLevel < level && app.thread != null &&
3710                     (level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
3711                             app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND)) {
3712                 try {
3713                     app.thread.scheduleTrimMemory(level);
3714                     app.trimMemoryLevel = level;
3715                     return true;
3716                 } catch (RemoteException e) {
3717                     // Fallthrough to failure case.
3718                 }
3719             }
3720         }
3721         return false;
3722     }
3723
3724     private void dispatchProcessesChanged() {
3725         int N;
3726         synchronized (this) {
3727             N = mPendingProcessChanges.size();
3728             if (mActiveProcessChanges.length < N) {
3729                 mActiveProcessChanges = new ProcessChangeItem[N];
3730             }
3731             mPendingProcessChanges.toArray(mActiveProcessChanges);
3732             mPendingProcessChanges.clear();
3733             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
3734                     "*** Delivering " + N + " process changes");
3735         }
3736
3737         int i = mProcessObservers.beginBroadcast();
3738         while (i > 0) {
3739             i--;
3740             final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3741             if (observer != null) {
3742                 try {
3743                     for (int j=0; j<N; j++) {
3744                         ProcessChangeItem item = mActiveProcessChanges[j];
3745                         if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3746                             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
3747                                     "ACTIVITIES CHANGED pid=" + item.pid + " uid="
3748                                     + item.uid + ": " + item.foregroundActivities);
3749                             observer.onForegroundActivitiesChanged(item.pid, item.uid,
3750                                     item.foregroundActivities);
3751                         }
3752                         if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3753                             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
3754                                     "PROCSTATE CHANGED pid=" + item.pid + " uid=" + item.uid
3755                                     + ": " + item.processState);
3756                             observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3757                         }
3758                     }
3759                 } catch (RemoteException e) {
3760                 }
3761             }
3762         }
3763         mProcessObservers.finishBroadcast();
3764
3765         synchronized (this) {
3766             for (int j=0; j<N; j++) {
3767                 mAvailProcessChanges.add(mActiveProcessChanges[j]);
3768             }
3769         }
3770     }
3771
3772     private void dispatchProcessDied(int pid, int uid) {
3773         int i = mProcessObservers.beginBroadcast();
3774         while (i > 0) {
3775             i--;
3776             final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3777             if (observer != null) {
3778                 try {
3779                     observer.onProcessDied(pid, uid);
3780                 } catch (RemoteException e) {
3781                 }
3782             }
3783         }
3784         mProcessObservers.finishBroadcast();
3785     }
3786
3787     private void dispatchUidsChanged() {
3788         int N;
3789         synchronized (this) {
3790             N = mPendingUidChanges.size();
3791             if (mActiveUidChanges.length < N) {
3792                 mActiveUidChanges = new UidRecord.ChangeItem[N];
3793             }
3794             for (int i=0; i<N; i++) {
3795                 final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
3796                 mActiveUidChanges[i] = change;
3797                 change.uidRecord.pendingChange = null;
3798                 change.uidRecord = null;
3799             }
3800             mPendingUidChanges.clear();
3801             if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
3802                     "*** Delivering " + N + " uid changes");
3803         }
3804
3805         if (mLocalPowerManager != null) {
3806             for (int j=0; j<N; j++) {
3807                 UidRecord.ChangeItem item = mActiveUidChanges[j];
3808                 if (item.gone) {
3809                     mLocalPowerManager.uidGone(item.uid);
3810                 } else {
3811                     mLocalPowerManager.updateUidProcState(item.uid, item.processState);
3812                 }
3813             }
3814         }
3815
3816         int i = mUidObservers.beginBroadcast();
3817         while (i > 0) {
3818             i--;
3819             final IUidObserver observer = mUidObservers.getBroadcastItem(i);
3820             if (observer != null) {
3821                 try {
3822                     for (int j=0; j<N; j++) {
3823                         UidRecord.ChangeItem item = mActiveUidChanges[j];
3824                         if (item.gone) {
3825                             if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
3826                                     "UID gone uid=" + item.uid);
3827                             observer.onUidGone(item.uid);
3828                         } else {
3829                             if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
3830                                     "UID CHANGED uid=" + item.uid
3831                                     + ": " + item.processState);
3832                             observer.onUidStateChanged(item.uid, item.processState);
3833                         }
3834                     }
3835                 } catch (RemoteException e) {
3836                 }
3837             }
3838         }
3839         mUidObservers.finishBroadcast();
3840
3841         synchronized (this) {
3842             for (int j=0; j<N; j++) {
3843                 mAvailUidChanges.add(mActiveUidChanges[j]);
3844             }
3845         }
3846     }
3847
3848     @Override
3849     public final int startActivity(IApplicationThread caller, String callingPackage,
3850             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3851             int startFlags, ProfilerInfo profilerInfo, Bundle options) {
3852         return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3853             resultWho, requestCode, startFlags, profilerInfo, options,
3854             UserHandle.getCallingUserId());
3855     }
3856
3857     @Override
3858     public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3859             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3860             int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3861         enforceNotIsolatedCaller("startActivity");
3862         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3863                 false, ALLOW_FULL_ONLY, "startActivity", null);
3864         // TODO: Switch to user app stacks here.
3865         return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3866                 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3867                 profilerInfo, null, null, options, false, userId, null, null);
3868     }
3869
3870     @Override
3871     public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
3872             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3873             int startFlags, ProfilerInfo profilerInfo, Bundle options, boolean ignoreTargetSecurity,
3874             int userId) {
3875
3876         // This is very dangerous -- it allows you to perform a start activity (including
3877         // permission grants) as any app that may launch one of your own activities.  So
3878         // we will only allow this to be done from activities that are part of the core framework,
3879         // and then only when they are running as the system.
3880         final ActivityRecord sourceRecord;
3881         final int targetUid;
3882         final String targetPackage;
3883         synchronized (this) {
3884             if (resultTo == null) {
3885                 throw new SecurityException("Must be called from an activity");
3886             }
3887             sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
3888             if (sourceRecord == null) {
3889                 throw new SecurityException("Called with bad activity token: " + resultTo);
3890             }
3891             if (!sourceRecord.info.packageName.equals("android")) {
3892                 throw new SecurityException(
3893                         "Must be called from an activity that is declared in the android package");
3894             }
3895             if (sourceRecord.app == null) {
3896                 throw new SecurityException("Called without a process attached to activity");
3897             }
3898             if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
3899                 // This is still okay, as long as this activity is running under the
3900                 // uid of the original calling activity.
3901                 if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
3902                     throw new SecurityException(
3903                             "Calling activity in uid " + sourceRecord.app.uid
3904                                     + " must be system uid or original calling uid "
3905                                     + sourceRecord.launchedFromUid);
3906                 }
3907             }
3908             if (ignoreTargetSecurity) {
3909                 if (intent.getComponent() == null) {
3910                     throw new SecurityException(
3911                             "Component must be specified with ignoreTargetSecurity");
3912                 }
3913                 if (intent.getSelector() != null) {
3914                     throw new SecurityException(
3915                             "Selector not allowed with ignoreTargetSecurity");
3916                 }
3917             }
3918             targetUid = sourceRecord.launchedFromUid;
3919             targetPackage = sourceRecord.launchedFromPackage;
3920         }
3921
3922         if (userId == UserHandle.USER_NULL) {
3923             userId = UserHandle.getUserId(sourceRecord.app.uid);
3924         }
3925
3926         // TODO: Switch to user app stacks here.
3927         try {
3928             int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent,
3929                     resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
3930                     null, null, options, ignoreTargetSecurity, userId, null, null);
3931             return ret;
3932         } catch (SecurityException e) {
3933             // XXX need to figure out how to propagate to original app.
3934             // A SecurityException here is generally actually a fault of the original
3935             // calling activity (such as a fairly granting permissions), so propagate it
3936             // back to them.
3937             /*
3938             StringBuilder msg = new StringBuilder();
3939             msg.append("While launching");
3940             msg.append(intent.toString());
3941             msg.append(": ");
3942             msg.append(e.getMessage());
3943             */
3944             throw e;
3945         }
3946     }
3947
3948     @Override
3949     public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3950             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3951             int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3952         enforceNotIsolatedCaller("startActivityAndWait");
3953         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3954                 false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
3955         WaitResult res = new WaitResult();
3956         // TODO: Switch to user app stacks here.
3957         mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3958                 null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
3959                 options, false, userId, null, null);
3960         return res;
3961     }
3962
3963     @Override
3964     public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3965             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3966             int startFlags, Configuration config, Bundle options, int userId) {
3967         enforceNotIsolatedCaller("startActivityWithConfig");
3968         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3969                 false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
3970         // TODO: Switch to user app stacks here.
3971         int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3972                 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3973                 null, null, config, options, false, userId, null, null);
3974         return ret;
3975     }
3976
3977     @Override
3978     public int startActivityIntentSender(IApplicationThread caller, IntentSender intent,
3979             Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho,
3980             int requestCode, int flagsMask, int flagsValues, Bundle options)
3981             throws TransactionTooLargeException {
3982         enforceNotIsolatedCaller("startActivityIntentSender");
3983         // Refuse possible leaked file descriptors
3984         if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3985             throw new IllegalArgumentException("File descriptors passed in Intent");
3986         }
3987
3988         IIntentSender sender = intent.getTarget();
3989         if (!(sender instanceof PendingIntentRecord)) {
3990             throw new IllegalArgumentException("Bad PendingIntent object");
3991         }
3992
3993         PendingIntentRecord pir = (PendingIntentRecord)sender;
3994
3995         synchronized (this) {
3996             // If this is coming from the currently resumed activity, it is
3997             // effectively saying that app switches are allowed at this point.
3998             final ActivityStack stack = getFocusedStack();
3999             if (stack.mResumedActivity != null &&
4000                     stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
4001                 mAppSwitchesAllowedTime = 0;
4002             }
4003         }
4004         int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
4005                 resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
4006         return ret;
4007     }
4008
4009     @Override
4010     public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
4011             Intent intent, String resolvedType, IVoiceInteractionSession session,
4012             IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
4013             Bundle options, int userId) {
4014         if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4015                 != PackageManager.PERMISSION_GRANTED) {
4016             String msg = "Permission Denial: startVoiceActivity() from pid="
4017                     + Binder.getCallingPid()
4018                     + ", uid=" + Binder.getCallingUid()
4019                     + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
4020             Slog.w(TAG, msg);
4021             throw new SecurityException(msg);
4022         }
4023         if (session == null || interactor == null) {
4024             throw new NullPointerException("null session or interactor");
4025         }
4026         userId = handleIncomingUser(callingPid, callingUid, userId,
4027                 false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
4028         // TODO: Switch to user app stacks here.
4029         return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
4030                 resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
4031                 null, options, false, userId, null, null);
4032     }
4033
4034     @Override
4035     public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
4036         synchronized (this) {
4037             if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
4038                 if (keepAwake) {
4039                     mVoiceWakeLock.acquire();
4040                 } else {
4041                     mVoiceWakeLock.release();
4042                 }
4043             }
4044         }
4045     }
4046
4047     @Override
4048     public boolean startNextMatchingActivity(IBinder callingActivity,
4049             Intent intent, Bundle options) {
4050         // Refuse possible leaked file descriptors
4051         if (intent != null && intent.hasFileDescriptors() == true) {
4052             throw new IllegalArgumentException("File descriptors passed in Intent");
4053         }
4054
4055         synchronized (this) {
4056             final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4057             if (r == null) {
4058                 ActivityOptions.abort(options);
4059                 return false;
4060             }
4061             if (r.app == null || r.app.thread == null) {
4062                 // The caller is not running...  d'oh!
4063                 ActivityOptions.abort(options);
4064                 return false;
4065             }
4066             intent = new Intent(intent);
4067             // The caller is not allowed to change the data.
4068             intent.setDataAndType(r.intent.getData(), r.intent.getType());
4069             // And we are resetting to find the next component...
4070             intent.setComponent(null);
4071
4072             final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4073
4074             ActivityInfo aInfo = null;
4075             try {
4076                 List<ResolveInfo> resolves =
4077                     AppGlobals.getPackageManager().queryIntentActivities(
4078                             intent, r.resolvedType,
4079                             PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4080                             UserHandle.getCallingUserId());
4081
4082                 // Look for the original activity in the list...
4083                 final int N = resolves != null ? resolves.size() : 0;
4084                 for (int i=0; i<N; i++) {
4085                     ResolveInfo rInfo = resolves.get(i);
4086                     if (rInfo.activityInfo.packageName.equals(r.packageName)
4087                             && rInfo.activityInfo.name.equals(r.info.name)) {
4088                         // We found the current one...  the next matching is
4089                         // after it.
4090                         i++;
4091                         if (i<N) {
4092                             aInfo = resolves.get(i).activityInfo;
4093                         }
4094                         if (debug) {
4095                             Slog.v(TAG, "Next matching activity: found current " + r.packageName
4096                                     + "/" + r.info.name);
4097                             Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
4098                                     + "/" + aInfo.name);
4099                         }
4100                         break;
4101                     }
4102                 }
4103             } catch (RemoteException e) {
4104             }
4105
4106             if (aInfo == null) {
4107                 // Nobody who is next!
4108                 ActivityOptions.abort(options);
4109                 if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4110                 return false;
4111             }
4112
4113             intent.setComponent(new ComponentName(
4114                     aInfo.applicationInfo.packageName, aInfo.name));
4115             intent.setFlags(intent.getFlags()&~(
4116                     Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4117                     Intent.FLAG_ACTIVITY_CLEAR_TOP|
4118                     Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4119                     Intent.FLAG_ACTIVITY_NEW_TASK));
4120
4121             // Okay now we need to start the new activity, replacing the
4122             // currently running activity.  This is a little tricky because
4123             // we want to start the new one as if the current one is finished,
4124             // but not finish the current one first so that there is no flicker.
4125             // And thus...
4126             final boolean wasFinishing = r.finishing;
4127             r.finishing = true;
4128
4129             // Propagate reply information over to the new activity.
4130             final ActivityRecord resultTo = r.resultTo;
4131             final String resultWho = r.resultWho;
4132             final int requestCode = r.requestCode;
4133             r.resultTo = null;
4134             if (resultTo != null) {
4135                 resultTo.removeResultsLocked(r, resultWho, requestCode);
4136             }
4137
4138             final long origId = Binder.clearCallingIdentity();
4139             int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
4140                     r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
4141                     resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage,
4142                     -1, r.launchedFromUid, 0, options, false, false, null, null, null);
4143             Binder.restoreCallingIdentity(origId);
4144
4145             r.finishing = wasFinishing;
4146             if (res != ActivityManager.START_SUCCESS) {
4147                 return false;
4148             }
4149             return true;
4150         }
4151     }
4152
4153     @Override
4154     public final int startActivityFromRecents(int taskId, Bundle options) {
4155         if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4156             String msg = "Permission Denial: startActivityFromRecents called without " +
4157                     START_TASKS_FROM_RECENTS;
4158             Slog.w(TAG, msg);
4159             throw new SecurityException(msg);
4160         }
4161         return startActivityFromRecentsInner(taskId, options);
4162     }
4163
4164     final int startActivityFromRecentsInner(int taskId, Bundle options) {
4165         final TaskRecord task;
4166         final int callingUid;
4167         final String callingPackage;
4168         final Intent intent;
4169         final int userId;
4170         synchronized (this) {
4171             task = mStackSupervisor.anyTaskForIdLocked(taskId);
4172             if (task == null) {
4173                 throw new IllegalArgumentException("Task " + taskId + " not found.");
4174             }
4175             if (task.getRootActivity() != null) {
4176                 moveTaskToFrontLocked(task.taskId, 0, null);
4177                 return ActivityManager.START_TASK_TO_FRONT;
4178             }
4179             callingUid = task.mCallingUid;
4180             callingPackage = task.mCallingPackage;
4181             intent = task.intent;
4182             intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
4183             userId = task.userId;
4184         }
4185         return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
4186                 options, userId, null, task);
4187     }
4188
4189     final int startActivityInPackage(int uid, String callingPackage,
4190             Intent intent, String resolvedType, IBinder resultTo,
4191             String resultWho, int requestCode, int startFlags, Bundle options, int userId,
4192             IActivityContainer container, TaskRecord inTask) {
4193
4194         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
4195                 false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4196
4197         // TODO: Switch to user app stacks here.
4198         int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent,
4199                 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4200                 null, null, null, options, false, userId, container, inTask);
4201         return ret;
4202     }
4203
4204     @Override
4205     public final int startActivities(IApplicationThread caller, String callingPackage,
4206             Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
4207             int userId) {
4208         enforceNotIsolatedCaller("startActivities");
4209         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
4210                 false, ALLOW_FULL_ONLY, "startActivity", null);
4211         // TODO: Switch to user app stacks here.
4212         int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
4213                 resolvedTypes, resultTo, options, userId);
4214         return ret;
4215     }
4216
4217     final int startActivitiesInPackage(int uid, String callingPackage,
4218             Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4219             Bundle options, int userId) {
4220
4221         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
4222                 false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4223         // TODO: Switch to user app stacks here.
4224         int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4225                 resultTo, options, userId);
4226         return ret;
4227     }
4228
4229     @Override
4230     public void reportActivityFullyDrawn(IBinder token) {
4231         synchronized (this) {
4232             ActivityRecord r = ActivityRecord.isInStackLocked(token);
4233             if (r == null) {
4234                 return;
4235             }
4236             r.reportFullyDrawnLocked();
4237         }
4238     }
4239
4240     @Override
4241     public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4242         synchronized (this) {
4243             ActivityRecord r = ActivityRecord.isInStackLocked(token);
4244             if (r == null) {
4245                 return;
4246             }
4247             if (r.task != null && r.task.mResizeable) {
4248                 // Fixed screen orientation isn't supported with resizeable activities.
4249                 return;
4250             }
4251             final long origId = Binder.clearCallingIdentity();
4252             mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4253             Configuration config = mWindowManager.updateOrientationFromAppTokens(
4254                     mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4255             if (config != null) {
4256                 r.frozenBeforeDestroy = true;
4257                 if (!updateConfigurationLocked(config, r, false, false)) {
4258                     mStackSupervisor.resumeTopActivitiesLocked();
4259                 }
4260             }
4261             Binder.restoreCallingIdentity(origId);
4262         }
4263     }
4264
4265     @Override
4266     public int getRequestedOrientation(IBinder token) {
4267         synchronized (this) {
4268             ActivityRecord r = ActivityRecord.isInStackLocked(token);
4269             if (r == null) {
4270                 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4271             }
4272             return mWindowManager.getAppOrientation(r.appToken);
4273         }
4274     }
4275
4276     /**
4277      * This is the internal entry point for handling Activity.finish().
4278      *
4279      * @param token The Binder token referencing the Activity we want to finish.
4280      * @param resultCode Result code, if any, from this Activity.
4281      * @param resultData Result data (Intent), if any, from this Activity.
4282      * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
4283      *            the root Activity in the task.
4284      *
4285      * @return Returns true if the activity successfully finished, or false if it is still running.
4286      */
4287     @Override
4288     public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4289             boolean finishTask) {
4290         // Refuse possible leaked file descriptors
4291         if (resultData != null && resultData.hasFileDescriptors() == true) {
4292             throw new IllegalArgumentException("File descriptors passed in Intent");
4293         }
4294
4295         synchronized(this) {
4296             ActivityRecord r = ActivityRecord.isInStackLocked(token);
4297             if (r == null) {
4298                 return true;
4299             }
4300             // Keep track of the root activity of the task before we finish it
4301             TaskRecord tr = r.task;
4302             ActivityRecord rootR = tr.getRootActivity();
4303             if (rootR == null) {
4304                 Slog.w(TAG, "Finishing task with all activities already finished");
4305             }
4306             // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
4307             // finish.
4308             if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
4309                     mStackSupervisor.isLastLockedTask(tr)) {
4310                 Slog.i(TAG, "Not finishing task in lock task mode");
4311                 mStackSupervisor.showLockTaskToast();
4312                 return false;
4313             }
4314             if (mController != null) {
4315                 // Find the first activity that is not finishing.
4316                 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4317                 if (next != null) {
4318                     // ask watcher if this is allowed
4319                     boolean resumeOK = true;
4320                     try {
4321                         resumeOK = mController.activityResuming(next.packageName);
4322                     } catch (RemoteException e) {
4323                         mController = null;
4324                         Watchdog.getInstance().setActivityController(null);
4325                     }
4326
4327                     if (!resumeOK) {
4328                         Slog.i(TAG, "Not finishing activity because controller resumed");
4329                         return false;
4330                     }
4331                 }
4332             }
4333             final long origId = Binder.clearCallingIdentity();
4334             try {
4335                 boolean res;
4336                 if (finishTask && r == rootR) {
4337                     // If requested, remove the task that is associated to this activity only if it
4338                     // was the root activity in the task. The result code and data is ignored
4339                     // because we don't support returning them across task boundaries.
4340                     res = removeTaskByIdLocked(tr.taskId, false);
4341                     if (!res) {
4342                         Slog.i(TAG, "Removing task failed to finish activity");
4343                     }
4344                 } else {
4345                     res = tr.stack.requestFinishActivityLocked(token, resultCode,
4346                             resultData, "app-request", true);
4347                     if (!res) {
4348                         Slog.i(TAG, "Failed to finish by app-request");
4349                     }
4350                 }
4351                 return res;
4352             } finally {
4353                 Binder.restoreCallingIdentity(origId);
4354             }
4355         }
4356     }
4357
4358     @Override
4359     public final void finishHeavyWeightApp() {
4360         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4361                 != PackageManager.PERMISSION_GRANTED) {
4362             String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4363                     + Binder.getCallingPid()
4364                     + ", uid=" + Binder.getCallingUid()
4365                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4366             Slog.w(TAG, msg);
4367             throw new SecurityException(msg);
4368         }
4369
4370         synchronized(this) {
4371             if (mHeavyWeightProcess == null) {
4372                 return;
4373             }
4374
4375             ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
4376             for (int i = 0; i < activities.size(); i++) {
4377                 ActivityRecord r = activities.get(i);
4378                 if (!r.finishing && r.isInStackLocked()) {
4379                     r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4380                             null, "finish-heavy", true);
4381                 }
4382             }
4383
4384             mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4385                     mHeavyWeightProcess.userId, 0));
4386             mHeavyWeightProcess = null;
4387         }
4388     }
4389
4390     @Override
4391     public void crashApplication(int uid, int initialPid, String packageName,
4392             String message) {
4393         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4394                 != PackageManager.PERMISSION_GRANTED) {
4395             String msg = "Permission Denial: crashApplication() from pid="
4396                     + Binder.getCallingPid()
4397                     + ", uid=" + Binder.getCallingUid()
4398                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4399             Slog.w(TAG, msg);
4400             throw new SecurityException(msg);
4401         }
4402
4403         synchronized(this) {
4404             ProcessRecord proc = null;
4405
4406             // Figure out which process to kill.  We don't trust that initialPid
4407             // still has any relation to current pids, so must scan through the
4408             // list.
4409             synchronized (mPidsSelfLocked) {
4410                 for (int i=0; i<mPidsSelfLocked.size(); i++) {
4411                     ProcessRecord p = mPidsSelfLocked.valueAt(i);
4412                     if (p.uid != uid) {
4413                         continue;
4414                     }
4415                     if (p.pid == initialPid) {
4416                         proc = p;
4417                         break;
4418                     }
4419                     if (p.pkgList.containsKey(packageName)) {
4420                         proc = p;
4421                     }
4422                 }
4423             }
4424
4425             if (proc == null) {
4426                 Slog.w(TAG, "crashApplication: nothing for uid=" + uid
4427                         + " initialPid=" + initialPid
4428                         + " packageName=" + packageName);
4429                 return;
4430             }
4431
4432             if (proc.thread != null) {
4433                 if (proc.pid == Process.myPid()) {
4434                     Log.w(TAG, "crashApplication: trying to crash self!");
4435                     return;
4436                 }
4437                 long ident = Binder.clearCallingIdentity();
4438                 try {
4439                     proc.thread.scheduleCrash(message);
4440                 } catch (RemoteException e) {
4441                 }
4442                 Binder.restoreCallingIdentity(ident);
4443             }
4444         }
4445     }
4446
4447     @Override
4448     public final void finishSubActivity(IBinder token, String resultWho,
4449             int requestCode) {
4450         synchronized(this) {
4451             final long origId = Binder.clearCallingIdentity();
4452             ActivityRecord r = ActivityRecord.isInStackLocked(token);
4453             if (r != null) {
4454                 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4455             }
4456             Binder.restoreCallingIdentity(origId);
4457         }
4458     }
4459
4460     @Override
4461     public boolean finishActivityAffinity(IBinder token) {
4462         synchronized(this) {
4463             final long origId = Binder.clearCallingIdentity();
4464             try {
4465                 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4466                 if (r == null) {
4467                     return false;
4468                 }
4469
4470                 // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
4471                 // can finish.
4472                 final TaskRecord task = r.task;
4473                 if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
4474                         mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
4475                     mStackSupervisor.showLockTaskToast();
4476                     return false;
4477                 }
4478                 return task.stack.finishActivityAffinityLocked(r);
4479             } finally {
4480                 Binder.restoreCallingIdentity(origId);
4481             }
4482         }
4483     }
4484
4485     @Override
4486     public void finishVoiceTask(IVoiceInteractionSession session) {
4487         synchronized(this) {
4488             final long origId = Binder.clearCallingIdentity();
4489             try {
4490                 mStackSupervisor.finishVoiceTask(session);
4491             } finally {
4492                 Binder.restoreCallingIdentity(origId);
4493             }
4494         }
4495
4496     }
4497
4498     @Override
4499     public boolean releaseActivityInstance(IBinder token) {
4500         synchronized(this) {
4501             final long origId = Binder.clearCallingIdentity();
4502             try {
4503                 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4504                 if (r == null) {
4505                     return false;
4506                 }
4507                 return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4508             } finally {
4509                 Binder.restoreCallingIdentity(origId);
4510             }
4511         }
4512     }
4513
4514     @Override
4515     public void releaseSomeActivities(IApplicationThread appInt) {
4516         synchronized(this) {
4517             final long origId = Binder.clearCallingIdentity();
4518             try {
4519                 ProcessRecord app = getRecordForAppLocked(appInt);
4520                 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4521             } finally {
4522                 Binder.restoreCallingIdentity(origId);
4523             }
4524         }
4525     }
4526
4527     @Override
4528     public boolean willActivityBeVisible(IBinder token) {
4529         synchronized(this) {
4530             ActivityStack stack = ActivityRecord.getStackLocked(token);
4531             if (stack != null) {
4532                 return stack.willActivityBeVisibleLocked(token);
4533             }
4534             return false;
4535         }
4536     }
4537
4538     @Override
4539     public void overridePendingTransition(IBinder token, String packageName,
4540             int enterAnim, int exitAnim) {
4541         synchronized(this) {
4542             ActivityRecord self = ActivityRecord.isInStackLocked(token);
4543             if (self == null) {
4544                 return;
4545             }
4546
4547             final long origId = Binder.clearCallingIdentity();
4548
4549             if (self.state == ActivityState.RESUMED
4550                     || self.state == ActivityState.PAUSING) {
4551                 mWindowManager.overridePendingAppTransition(packageName,
4552                         enterAnim, exitAnim, null);
4553             }
4554
4555             Binder.restoreCallingIdentity(origId);
4556         }
4557     }
4558
4559     /**
4560      * Main function for removing an existing process from the activity manager
4561      * as a result of that process going away.  Clears out all connections
4562      * to the process.
4563      */
4564     private final void handleAppDiedLocked(ProcessRecord app,
4565             boolean restarting, boolean allowRestart) {
4566         int pid = app.pid;
4567         boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4568         if (!kept && !restarting) {
4569             removeLruProcessLocked(app);
4570             if (pid > 0) {
4571                 ProcessList.remove(pid);
4572             }
4573         }
4574
4575         if (mProfileProc == app) {
4576             clearProfilerLocked();
4577         }
4578
4579         // Remove this application's activities from active lists.
4580         boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4581
4582         app.activities.clear();
4583
4584         if (app.instrumentationClass != null) {
4585             Slog.w(TAG, "Crash of app " + app.processName
4586                   + " running instrumentation " + app.instrumentationClass);
4587             Bundle info = new Bundle();
4588             info.putString("shortMsg", "Process crashed.");
4589             finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4590         }
4591
4592         if (!restarting && hasVisibleActivities && !mStackSupervisor.resumeTopActivitiesLocked()) {
4593             // If there was nothing to resume, and we are not already
4594             // restarting this process, but there is a visible activity that
4595             // is hosted by the process...  then make sure all visible
4596             // activities are running, taking care of restarting this
4597             // process.
4598             mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
4599         }
4600     }
4601
4602     private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4603         IBinder threadBinder = thread.asBinder();
4604         // Find the application record.
4605         for (int i=mLruProcesses.size()-1; i>=0; i--) {
4606             ProcessRecord rec = mLruProcesses.get(i);
4607             if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4608                 return i;
4609             }
4610         }
4611         return -1;
4612     }
4613
4614     final ProcessRecord getRecordForAppLocked(
4615             IApplicationThread thread) {
4616         if (thread == null) {
4617             return null;
4618         }
4619
4620         int appIndex = getLRURecordIndexForAppLocked(thread);
4621         return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4622     }
4623
4624     final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4625         // If there are no longer any background processes running,
4626         // and the app that died was not running instrumentation,
4627         // then tell everyone we are now low on memory.
4628         boolean haveBg = false;
4629         for (int i=mLruProcesses.size()-1; i>=0; i--) {
4630             ProcessRecord rec = mLruProcesses.get(i);
4631             if (rec.thread != null
4632                     && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4633                 haveBg = true;
4634                 break;
4635             }
4636         }
4637
4638         if (!haveBg) {
4639             boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4640             if (doReport) {
4641                 long now = SystemClock.uptimeMillis();
4642                 if (now < (mLastMemUsageReportTime+5*60*1000)) {
4643                     doReport = false;
4644                 } else {
4645                     mLastMemUsageReportTime = now;
4646                 }
4647             }
4648             final ArrayList<ProcessMemInfo> memInfos
4649                     = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4650             EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4651             long now = SystemClock.uptimeMillis();
4652             for (int i=mLruProcesses.size()-1; i>=0; i--) {
4653                 ProcessRecord rec = mLruProcesses.get(i);
4654                 if (rec == dyingProc || rec.thread == null) {
4655                     continue;
4656                 }
4657                 if (doReport) {
4658                     memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4659                             rec.setProcState, rec.adjType, rec.makeAdjReason()));
4660                 }
4661                 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4662                     // The low memory report is overriding any current
4663                     // state for a GC request.  Make sure to do
4664                     // heavy/important/visible/foreground processes first.
4665                     if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4666                         rec.lastRequestedGc = 0;
4667                     } else {
4668                         rec.lastRequestedGc = rec.lastLowMemory;
4669                     }
4670                     rec.reportLowMemory = true;
4671                     rec.lastLowMemory = now;
4672                     mProcessesToGc.remove(rec);
4673                     addProcessToGcListLocked(rec);
4674                 }
4675             }
4676             if (doReport) {
4677                 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4678                 mHandler.sendMessage(msg);
4679             }
4680             scheduleAppGcsLocked();
4681         }
4682     }
4683
4684     final void appDiedLocked(ProcessRecord app) {
4685        appDiedLocked(app, app.pid, app.thread, false);
4686     }
4687
4688     final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
4689             boolean fromBinderDied) {
4690         // First check if this ProcessRecord is actually active for the pid.
4691         synchronized (mPidsSelfLocked) {
4692             ProcessRecord curProc = mPidsSelfLocked.get(pid);
4693             if (curProc != app) {
4694                 Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
4695                 return;
4696             }
4697         }
4698
4699         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4700         synchronized (stats) {
4701             stats.noteProcessDiedLocked(app.info.uid, pid);
4702         }
4703
4704         if (!app.killed) {
4705             if (!fromBinderDied) {
4706                 Process.killProcessQuiet(pid);
4707             }
4708             killProcessGroup(app.info.uid, pid);
4709             app.killed = true;
4710         }
4711
4712         // Clean up already done if the process has been re-started.
4713         if (app.pid == pid && app.thread != null &&
4714                 app.thread.asBinder() == thread.asBinder()) {
4715             boolean doLowMem = app.instrumentationClass == null;
4716             boolean doOomAdj = doLowMem;
4717             if (!app.killedByAm) {
4718                 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4719                         + ") has died");
4720                 mAllowLowerMemLevel = true;
4721             } else {
4722                 // Note that we always want to do oom adj to update our state with the
4723                 // new number of procs.
4724                 mAllowLowerMemLevel = false;
4725                 doLowMem = false;
4726             }
4727             EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4728             if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
4729                 "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
4730             handleAppDiedLocked(app, false, true);
4731
4732             if (doOomAdj) {
4733                 updateOomAdjLocked();
4734             }
4735             if (doLowMem) {
4736                 doLowMemReportIfNeededLocked(app);
4737             }
4738         } else if (app.pid != pid) {
4739             // A new process has already been started.
4740             Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4741                     + ") has died and restarted (pid " + app.pid + ").");
4742             EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4743         } else if (DEBUG_PROCESSES) {
4744             Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
4745                     + thread.asBinder());
4746         }
4747     }
4748
4749     /**
4750      * If a stack trace dump file is configured, dump process stack traces.
4751      * @param clearTraces causes the dump file to be erased prior to the new
4752      *    traces being written, if true; when false, the new traces will be
4753      *    appended to any existing file content.
4754      * @param firstPids of dalvik VM processes to dump stack traces for first
4755      * @param lastPids of dalvik VM processes to dump stack traces for last
4756      * @param nativeProcs optional list of native process names to dump stack crawls
4757      * @return file containing stack traces, or null if no dump file is configured
4758      */
4759     public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4760             ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4761         String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4762         if (tracesPath == null || tracesPath.length() == 0) {
4763             return null;
4764         }
4765
4766         File tracesFile = new File(tracesPath);
4767         try {
4768             File tracesDir = tracesFile.getParentFile();
4769             if (!tracesDir.exists()) {
4770                 tracesDir.mkdirs();
4771                 if (!SELinux.restorecon(tracesDir)) {
4772                     return null;
4773                 }
4774             }
4775             FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4776
4777             if (clearTraces && tracesFile.exists()) tracesFile.delete();
4778             tracesFile.createNewFile();
4779             FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4780         } catch (IOException e) {
4781             Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4782             return null;
4783         }
4784
4785         dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4786         return tracesFile;
4787     }
4788
4789     private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4790             ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4791         // Use a FileObserver to detect when traces finish writing.
4792         // The order of traces is considered important to maintain for legibility.
4793         FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4794             @Override
4795             public synchronized void onEvent(int event, String path) { notify(); }
4796         };
4797
4798         try {
4799             observer.startWatching();
4800
4801             // First collect all of the stacks of the most important pids.
4802             if (firstPids != null) {
4803                 try {
4804                     int num = firstPids.size();
4805                     for (int i = 0; i < num; i++) {
4806                         synchronized (observer) {
4807                             Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4808                             observer.wait(200);  // Wait for write-close, give up after 200msec
4809                         }
4810                     }
4811                 } catch (InterruptedException e) {
4812                     Slog.wtf(TAG, e);
4813                 }
4814             }
4815
4816             // Next collect the stacks of the native pids
4817             if (nativeProcs != null) {
4818                 int[] pids = Process.getPidsForCommands(nativeProcs);
4819                 if (pids != null) {
4820                     for (int pid : pids) {
4821                         Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4822                     }
4823                 }
4824             }
4825
4826             // Lastly, measure CPU usage.
4827             if (processCpuTracker != null) {
4828                 processCpuTracker.init();
4829                 System.gc();
4830                 processCpuTracker.update();
4831                 try {
4832                     synchronized (processCpuTracker) {
4833                         processCpuTracker.wait(500); // measure over 1/2 second.
4834                     }
4835                 } catch (InterruptedException e) {
4836                 }
4837                 processCpuTracker.update();
4838
4839                 // We'll take the stack crawls of just the top apps using CPU.
4840                 final int N = processCpuTracker.countWorkingStats();
4841                 int numProcs = 0;
4842                 for (int i=0; i<N && numProcs<5; i++) {
4843                     ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4844                     if (lastPids.indexOfKey(stats.pid) >= 0) {
4845                         numProcs++;
4846                         try {
4847                             synchronized (observer) {
4848                                 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4849                                 observer.wait(200);  // Wait for write-close, give up after 200msec
4850                             }
4851                         } catch (InterruptedException e) {
4852                             Slog.wtf(TAG, e);
4853                         }
4854
4855                     }
4856                 }
4857             }
4858         } finally {
4859             observer.stopWatching();
4860         }
4861     }
4862
4863     final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4864         if (true || IS_USER_BUILD) {
4865             return;
4866         }
4867         String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4868         if (tracesPath == null || tracesPath.length() == 0) {
4869             return;
4870         }
4871
4872         StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4873         StrictMode.allowThreadDiskWrites();
4874         try {
4875             final File tracesFile = new File(tracesPath);
4876             final File tracesDir = tracesFile.getParentFile();
4877             final File tracesTmp = new File(tracesDir, "__tmp__");
4878             try {
4879                 if (!tracesDir.exists()) {
4880                     tracesDir.mkdirs();
4881                     if (!SELinux.restorecon(tracesDir.getPath())) {
4882                         return;
4883                     }
4884                 }
4885                 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4886
4887                 if (tracesFile.exists()) {
4888                     tracesTmp.delete();
4889                     tracesFile.renameTo(tracesTmp);
4890                 }
4891                 StringBuilder sb = new StringBuilder();
4892                 Time tobj = new Time();
4893                 tobj.set(System.currentTimeMillis());
4894                 sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4895                 sb.append(": ");
4896                 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4897                 sb.append(" since ");
4898                 sb.append(msg);
4899                 FileOutputStream fos = new FileOutputStream(tracesFile);
4900                 fos.write(sb.toString().getBytes());
4901                 if (app == null) {
4902                     fos.write("\n*** No application process!".getBytes());
4903                 }
4904                 fos.close();
4905                 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4906             } catch (IOException e) {
4907                 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4908                 return;
4909             }
4910
4911             if (app != null) {
4912                 ArrayList<Integer> firstPids = new ArrayList<Integer>();
4913                 firstPids.add(app.pid);
4914                 dumpStackTraces(tracesPath, firstPids, null, null, null);
4915             }
4916
4917             File lastTracesFile = null;
4918             File curTracesFile = null;
4919             for (int i=9; i>=0; i--) {
4920                 String name = String.format(Locale.US, "slow%02d.txt", i);
4921                 curTracesFile = new File(tracesDir, name);
4922                 if (curTracesFile.exists()) {
4923                     if (lastTracesFile != null) {
4924                         curTracesFile.renameTo(lastTracesFile);
4925                     } else {
4926                         curTracesFile.delete();
4927                     }
4928                 }
4929                 lastTracesFile = curTracesFile;
4930             }
4931             tracesFile.renameTo(curTracesFile);
4932             if (tracesTmp.exists()) {
4933                 tracesTmp.renameTo(tracesFile);
4934             }
4935         } finally {
4936             StrictMode.setThreadPolicy(oldPolicy);
4937         }
4938     }
4939
4940     final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4941             ActivityRecord parent, boolean aboveSystem, final String annotation) {
4942         ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4943         SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4944
4945         if (mController != null) {
4946             try {
4947                 // 0 == continue, -1 = kill process immediately
4948                 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4949                 if (res < 0 && app.pid != MY_PID) {
4950                     app.kill("anr", true);
4951                 }
4952             } catch (RemoteException e) {
4953                 mController = null;
4954                 Watchdog.getInstance().setActivityController(null);
4955             }
4956         }
4957
4958         long anrTime = SystemClock.uptimeMillis();
4959         if (MONITOR_CPU_USAGE) {
4960             updateCpuStatsNow();
4961         }
4962
4963         synchronized (this) {
4964             // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4965             if (mShuttingDown) {
4966                 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4967                 return;
4968             } else if (app.notResponding) {
4969                 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4970                 return;
4971             } else if (app.crashing) {
4972                 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4973                 return;
4974             }
4975
4976             // In case we come through here for the same app before completing
4977             // this one, mark as anring now so we will bail out.
4978             app.notResponding = true;
4979
4980             // Log the ANR to the event log.
4981             EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4982                     app.processName, app.info.flags, annotation);
4983
4984             // Dump thread traces as quickly as we can, starting with "interesting" processes.
4985             firstPids.add(app.pid);
4986
4987             int parentPid = app.pid;
4988             if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4989             if (parentPid != app.pid) firstPids.add(parentPid);
4990
4991             if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4992
4993             for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4994                 ProcessRecord r = mLruProcesses.get(i);
4995                 if (r != null && r.thread != null) {
4996                     int pid = r.pid;
4997                     if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4998                         if (r.persistent) {
4999                             firstPids.add(pid);
5000                         } else {
5001                             lastPids.put(pid, Boolean.TRUE);
5002                         }
5003                     }
5004                 }
5005             }
5006         }
5007
5008         // Log the ANR to the main log.
5009         StringBuilder info = new StringBuilder();
5010         info.setLength(0);
5011         info.append("ANR in ").append(app.processName);
5012         if (activity != null && activity.shortComponentName != null) {
5013             info.append(" (").append(activity.shortComponentName).append(")");
5014         }
5015         info.append("\n");
5016         info.append("PID: ").append(app.pid).append("\n");
5017         if (annotation != null) {
5018             info.append("Reason: ").append(annotation).append("\n");
5019         }
5020         if (parent != null && parent != activity) {
5021             info.append("Parent: ").append(parent.shortComponentName).append("\n");
5022         }
5023
5024         final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
5025
5026         File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
5027                 NATIVE_STACKS_OF_INTEREST);
5028
5029         String cpuInfo = null;
5030         if (MONITOR_CPU_USAGE) {
5031             updateCpuStatsNow();
5032             synchronized (mProcessCpuTracker) {
5033                 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
5034             }
5035             info.append(processCpuTracker.printCurrentLoad());
5036             info.append(cpuInfo);
5037         }
5038
5039         info.append(processCpuTracker.printCurrentState(anrTime));
5040
5041         Slog.e(TAG, info.toString());
5042         if (tracesFile == null) {
5043             // There is no trace file, so dump (only) the alleged culprit's threads to the log
5044             Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
5045         }
5046
5047         addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
5048                 cpuInfo, tracesFile, null);
5049
5050         if (mController != null) {
5051             try {
5052                 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
5053                 int res = mController.appNotResponding(app.processName, app.pid, info.toString());
5054                 if (res != 0) {
5055                     if (res < 0 && app.pid != MY_PID) {
5056                         app.kill("anr", true);
5057                     } else {
5058                         synchronized (this) {
5059                             mServices.scheduleServiceTimeoutLocked(app);
5060                         }
5061                     }
5062                     return;
5063                 }
5064             } catch (RemoteException e) {
5065                 mController = null;
5066                 Watchdog.getInstance().setActivityController(null);
5067             }
5068         }
5069
5070         // Unless configured otherwise, swallow ANRs in background processes & kill the process.
5071         boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
5072                 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
5073
5074         synchronized (this) {
5075             mBatteryStatsService.noteProcessAnr(app.processName, app.uid);
5076
5077             if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
5078                 app.kill("bg anr", true);
5079                 return;
5080             }
5081
5082             // Set the app's notResponding state, and look up the errorReportReceiver
5083             makeAppNotRespondingLocked(app,
5084                     activity != null ? activity.shortComponentName : null,
5085                     annotation != null ? "ANR " + annotation : "ANR",
5086                     info.toString());
5087
5088             // Bring up the infamous App Not Responding dialog
5089             Message msg = Message.obtain();
5090             HashMap<String, Object> map = new HashMap<String, Object>();
5091             msg.what = SHOW_NOT_RESPONDING_MSG;
5092             msg.obj = map;
5093             msg.arg1 = aboveSystem ? 1 : 0;
5094             map.put("app", app);
5095             if (activity != null) {
5096                 map.put("activity", activity);
5097             }
5098
5099             mUiHandler.sendMessage(msg);
5100         }
5101     }
5102
5103     final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5104         if (!mLaunchWarningShown) {
5105             mLaunchWarningShown = true;
5106             mUiHandler.post(new Runnable() {
5107                 @Override
5108                 public void run() {
5109                     synchronized (ActivityManagerService.this) {
5110                         final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5111                         d.show();
5112                         mUiHandler.postDelayed(new Runnable() {
5113                             @Override
5114                             public void run() {
5115                                 synchronized (ActivityManagerService.this) {
5116                                     d.dismiss();
5117                                     mLaunchWarningShown = false;
5118                                 }
5119                             }
5120                         }, 4000);
5121                     }
5122                 }
5123             });
5124         }
5125     }
5126
5127     @Override
5128     public boolean clearApplicationUserData(final String packageName,
5129             final IPackageDataObserver observer, int userId) {
5130         enforceNotIsolatedCaller("clearApplicationUserData");
5131         if (packageName != null && packageName.equals(mDeviceOwnerName)) {
5132             throw new SecurityException("Clearing DeviceOwner data is forbidden.");
5133         }
5134         int uid = Binder.getCallingUid();
5135         int pid = Binder.getCallingPid();
5136         userId = handleIncomingUser(pid, uid,
5137                 userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5138         long callingId = Binder.clearCallingIdentity();
5139         try {
5140             IPackageManager pm = AppGlobals.getPackageManager();
5141             int pkgUid = -1;
5142             synchronized(this) {
5143                 try {
5144                     pkgUid = pm.getPackageUid(packageName, userId);
5145                 } catch (RemoteException e) {
5146                 }
5147                 if (pkgUid == -1) {
5148                     Slog.w(TAG, "Invalid packageName: " + packageName);
5149                     if (observer != null) {
5150                         try {
5151                             observer.onRemoveCompleted(packageName, false);
5152                         } catch (RemoteException e) {
5153                             Slog.i(TAG, "Observer no longer exists.");
5154                         }
5155                     }
5156                     return false;
5157                 }
5158                 if (uid == pkgUid || checkComponentPermission(
5159                         android.Manifest.permission.CLEAR_APP_USER_DATA,
5160                         pid, uid, -1, true)
5161                         == PackageManager.PERMISSION_GRANTED) {
5162                     forceStopPackageLocked(packageName, pkgUid, "clear data");
5163                 } else {
5164                     throw new SecurityException("PID " + pid + " does not have permission "
5165                             + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5166                                     + " of package " + packageName);
5167                 }
5168
5169                 // Remove all tasks match the cleared application package and user
5170                 for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5171                     final TaskRecord tr = mRecentTasks.get(i);
5172                     final String taskPackageName =
5173                             tr.getBaseIntent().getComponent().getPackageName();
5174                     if (tr.userId != userId) continue;
5175                     if (!taskPackageName.equals(packageName)) continue;
5176                     removeTaskByIdLocked(tr.taskId, false);
5177                 }
5178             }
5179
5180             try {
5181                 // Clear application user data
5182                 pm.clearApplicationUserData(packageName, observer, userId);
5183
5184                 synchronized(this) {
5185                     // Remove all permissions granted from/to this package
5186                     removeUriPermissionsForPackageLocked(packageName, userId, true);
5187                 }
5188
5189                 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5190                         Uri.fromParts("package", packageName, null));
5191                 intent.putExtra(Intent.EXTRA_UID, pkgUid);
5192                 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5193                         null, null, 0, null, null, null, null, false, false, userId);
5194             } catch (RemoteException e) {
5195             }
5196         } finally {
5197             Binder.restoreCallingIdentity(callingId);
5198         }
5199         return true;
5200     }
5201
5202     @Override
5203     public void killBackgroundProcesses(final String packageName, int userId) {
5204         if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5205                 != PackageManager.PERMISSION_GRANTED &&
5206                 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5207                         != PackageManager.PERMISSION_GRANTED) {
5208             String msg = "Permission Denial: killBackgroundProcesses() from pid="
5209                     + Binder.getCallingPid()
5210                     + ", uid=" + Binder.getCallingUid()
5211                     + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5212             Slog.w(TAG, msg);
5213             throw new SecurityException(msg);
5214         }
5215
5216         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5217                 userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5218         long callingId = Binder.clearCallingIdentity();
5219         try {
5220             IPackageManager pm = AppGlobals.getPackageManager();
5221             synchronized(this) {
5222                 int appId = -1;
5223                 try {
5224                     appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
5225                 } catch (RemoteException e) {
5226                 }
5227                 if (appId == -1) {
5228                     Slog.w(TAG, "Invalid packageName: " + packageName);
5229                     return;
5230                 }
5231                 killPackageProcessesLocked(packageName, appId, userId,
5232                         ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5233             }
5234         } finally {
5235             Binder.restoreCallingIdentity(callingId);
5236         }
5237     }
5238
5239     @Override
5240     public void killAllBackgroundProcesses() {
5241         if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5242                 != PackageManager.PERMISSION_GRANTED) {
5243             String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5244                     + Binder.getCallingPid()
5245                     + ", uid=" + Binder.getCallingUid()
5246                     + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5247             Slog.w(TAG, msg);
5248             throw new SecurityException(msg);
5249         }
5250
5251         long callingId = Binder.clearCallingIdentity();
5252         try {
5253             synchronized(this) {
5254                 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5255                 final int NP = mProcessNames.getMap().size();
5256                 for (int ip=0; ip<NP; ip++) {
5257                     SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5258                     final int NA = apps.size();
5259                     for (int ia=0; ia<NA; ia++) {
5260                         ProcessRecord app = apps.valueAt(ia);
5261                         if (app.persistent) {
5262                             // we don't kill persistent processes
5263                             continue;
5264                         }
5265                         if (app.removed) {
5266                             procs.add(app);
5267                         } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5268                             app.removed = true;
5269                             procs.add(app);
5270                         }
5271                     }
5272                 }
5273
5274                 int N = procs.size();
5275                 for (int i=0; i<N; i++) {
5276                     removeProcessLocked(procs.get(i), false, true, "kill all background");
5277                 }
5278                 mAllowLowerMemLevel = true;
5279                 updateOomAdjLocked();
5280                 doLowMemReportIfNeededLocked(null);
5281             }
5282         } finally {
5283             Binder.restoreCallingIdentity(callingId);
5284         }
5285     }
5286
5287     @Override
5288     public void forceStopPackage(final String packageName, int userId) {
5289         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5290                 != PackageManager.PERMISSION_GRANTED) {
5291             String msg = "Permission Denial: forceStopPackage() from pid="
5292                     + Binder.getCallingPid()
5293                     + ", uid=" + Binder.getCallingUid()
5294                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5295             Slog.w(TAG, msg);
5296             throw new SecurityException(msg);
5297         }
5298         final int callingPid = Binder.getCallingPid();
5299         userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
5300                 userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5301         long callingId = Binder.clearCallingIdentity();
5302         try {
5303             IPackageManager pm = AppGlobals.getPackageManager();
5304             synchronized(this) {
5305                 int[] users = userId == UserHandle.USER_ALL
5306                         ? getUsersLocked() : new int[] { userId };
5307                 for (int user : users) {
5308                     int pkgUid = -1;
5309                     try {
5310                         pkgUid = pm.getPackageUid(packageName, user);
5311                     } catch (RemoteException e) {
5312                     }
5313                     if (pkgUid == -1) {
5314                         Slog.w(TAG, "Invalid packageName: " + packageName);
5315                         continue;
5316                     }
5317                     try {
5318                         pm.setPackageStoppedState(packageName, true, user);
5319                     } catch (RemoteException e) {
5320                     } catch (IllegalArgumentException e) {
5321                         Slog.w(TAG, "Failed trying to unstop package "
5322                                 + packageName + ": " + e);
5323                     }
5324                     if (isUserRunningLocked(user, false)) {
5325                         forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5326                     }
5327                 }
5328             }
5329         } finally {
5330             Binder.restoreCallingIdentity(callingId);
5331         }
5332     }
5333
5334     @Override
5335     public void addPackageDependency(String packageName) {
5336         synchronized (this) {
5337             int callingPid = Binder.getCallingPid();
5338             if (callingPid == Process.myPid()) {
5339                 //  Yeah, um, no.
5340                 return;
5341             }
5342             ProcessRecord proc;
5343             synchronized (mPidsSelfLocked) {
5344                 proc = mPidsSelfLocked.get(Binder.getCallingPid());
5345             }
5346             if (proc != null) {
5347                 if (proc.pkgDeps == null) {
5348                     proc.pkgDeps = new ArraySet<String>(1);
5349                 }
5350                 proc.pkgDeps.add(packageName);
5351             }
5352         }
5353     }
5354
5355     /*
5356      * The pkg name and app id have to be specified.
5357      */
5358     @Override
5359     public void killApplicationWithAppId(String pkg, int appid, String reason) {
5360         if (pkg == null) {
5361             return;
5362         }
5363         // Make sure the uid is valid.
5364         if (appid < 0) {
5365             Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5366             return;
5367         }
5368         int callerUid = Binder.getCallingUid();
5369         // Only the system server can kill an application
5370         if (UserHandle.getAppId(callerUid) == Process.SYSTEM_UID) {
5371             // Post an aysnc message to kill the application
5372             Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5373             msg.arg1 = appid;
5374             msg.arg2 = 0;
5375             Bundle bundle = new Bundle();
5376             bundle.putString("pkg", pkg);
5377             bundle.putString("reason", reason);
5378             msg.obj = bundle;
5379             mHandler.sendMessage(msg);
5380         } else {
5381             throw new SecurityException(callerUid + " cannot kill pkg: " +
5382                     pkg);
5383         }
5384     }
5385
5386     @Override
5387     public void closeSystemDialogs(String reason) {
5388         enforceNotIsolatedCaller("closeSystemDialogs");
5389
5390         final int pid = Binder.getCallingPid();
5391         final int uid = Binder.getCallingUid();
5392         final long origId = Binder.clearCallingIdentity();
5393         try {
5394             synchronized (this) {
5395                 // Only allow this from foreground processes, so that background
5396                 // applications can't abuse it to prevent system UI from being shown.
5397                 if (uid >= Process.FIRST_APPLICATION_UID) {
5398                     ProcessRecord proc;
5399                     synchronized (mPidsSelfLocked) {
5400                         proc = mPidsSelfLocked.get(pid);
5401                     }
5402                     if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5403                         Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5404                                 + " from background process " + proc);
5405                         return;
5406                     }
5407                 }
5408                 closeSystemDialogsLocked(reason);
5409             }
5410         } finally {
5411             Binder.restoreCallingIdentity(origId);
5412         }
5413     }
5414
5415     void closeSystemDialogsLocked(String reason) {
5416         Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5417         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5418                 | Intent.FLAG_RECEIVER_FOREGROUND);
5419         if (reason != null) {
5420             intent.putExtra("reason", reason);
5421         }
5422         mWindowManager.closeSystemDialogs(reason);
5423
5424         mStackSupervisor.closeSystemDialogsLocked();
5425
5426         broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
5427                 AppOpsManager.OP_NONE, null, false, false,
5428                 -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
5429     }
5430
5431     @Override
5432     public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5433         enforceNotIsolatedCaller("getProcessMemoryInfo");
5434         Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5435         for (int i=pids.length-1; i>=0; i--) {
5436             ProcessRecord proc;
5437             int oomAdj;
5438             synchronized (this) {
5439                 synchronized (mPidsSelfLocked) {
5440                     proc = mPidsSelfLocked.get(pids[i]);
5441                     oomAdj = proc != null ? proc.setAdj : 0;
5442                 }
5443             }
5444             infos[i] = new Debug.MemoryInfo();
5445             Debug.getMemoryInfo(pids[i], infos[i]);
5446             if (proc != null) {
5447                 synchronized (this) {
5448                     if (proc.thread != null && proc.setAdj == oomAdj) {
5449                         // Record this for posterity if the process has been stable.
5450                         proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5451                                 infos[i].getTotalUss(), false, proc.pkgList);
5452                     }
5453                 }
5454             }
5455         }
5456         return infos;
5457     }
5458
5459     @Override
5460     public long[] getProcessPss(int[] pids) {
5461         enforceNotIsolatedCaller("getProcessPss");
5462         long[] pss = new long[pids.length];
5463         for (int i=pids.length-1; i>=0; i--) {
5464             ProcessRecord proc;
5465             int oomAdj;
5466             synchronized (this) {
5467                 synchronized (mPidsSelfLocked) {
5468                     proc = mPidsSelfLocked.get(pids[i]);
5469                     oomAdj = proc != null ? proc.setAdj : 0;
5470                 }
5471             }
5472             long[] tmpUss = new long[1];
5473             pss[i] = Debug.getPss(pids[i], tmpUss, null);
5474             if (proc != null) {
5475                 synchronized (this) {
5476                     if (proc.thread != null && proc.setAdj == oomAdj) {
5477                         // Record this for posterity if the process has been stable.
5478                         proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5479                     }
5480                 }
5481             }
5482         }
5483         return pss;
5484     }
5485
5486     @Override
5487     public void killApplicationProcess(String processName, int uid) {
5488         if (processName == null) {
5489             return;
5490         }
5491
5492         int callerUid = Binder.getCallingUid();
5493         // Only the system server can kill an application
5494         if (callerUid == Process.SYSTEM_UID) {
5495             synchronized (this) {
5496                 ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5497                 if (app != null && app.thread != null) {
5498                     try {
5499                         app.thread.scheduleSuicide();
5500                     } catch (RemoteException e) {
5501                         // If the other end already died, then our work here is done.
5502                     }
5503                 } else {
5504                     Slog.w(TAG, "Process/uid not found attempting kill of "
5505                             + processName + " / " + uid);
5506                 }
5507             }
5508         } else {
5509             throw new SecurityException(callerUid + " cannot kill app process: " +
5510                     processName);
5511         }
5512     }
5513
5514     private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5515         forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5516                 false, true, false, false, UserHandle.getUserId(uid), reason);
5517         Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5518                 Uri.fromParts("package", packageName, null));
5519         if (!mProcessesReady) {
5520             intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5521                     | Intent.FLAG_RECEIVER_FOREGROUND);
5522         }
5523         intent.putExtra(Intent.EXTRA_UID, uid);
5524         intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5525         broadcastIntentLocked(null, null, intent,
5526                 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5527                 null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5528     }
5529
5530     private void forceStopUserLocked(int userId, String reason) {
5531         forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
5532         Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
5533         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5534                 | Intent.FLAG_RECEIVER_FOREGROUND);
5535         intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5536         broadcastIntentLocked(null, null, intent,
5537                 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5538                 null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
5539     }
5540
5541     private final boolean killPackageProcessesLocked(String packageName, int appId,
5542             int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5543             boolean doit, boolean evenPersistent, String reason) {
5544         ArrayList<ProcessRecord> procs = new ArrayList<>();
5545
5546         // Remove all processes this package may have touched: all with the
5547         // same UID (except for the system or root user), and all whose name
5548         // matches the package name.
5549         final int NP = mProcessNames.getMap().size();
5550         for (int ip=0; ip<NP; ip++) {
5551             SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5552             final int NA = apps.size();
5553             for (int ia=0; ia<NA; ia++) {
5554                 ProcessRecord app = apps.valueAt(ia);
5555                 if (app.persistent && !evenPersistent) {
5556                     // we don't kill persistent processes
5557                     continue;
5558                 }
5559                 if (app.removed) {
5560                     if (doit) {
5561                         procs.add(app);
5562                     }
5563                     continue;
5564                 }
5565
5566                 // Skip process if it doesn't meet our oom adj requirement.
5567                 if (app.setAdj < minOomAdj) {
5568                     continue;
5569                 }
5570
5571                 // If no package is specified, we call all processes under the
5572                 // give user id.
5573                 if (packageName == null) {
5574                     if (userId != UserHandle.USER_ALL && app.userId != userId) {
5575                         continue;
5576                     }
5577                     if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5578                         continue;
5579                     }
5580                 // Package has been specified, we want to hit all processes
5581                 // that match it.  We need to qualify this by the processes
5582                 // that are running under the specified app and user ID.
5583                 } else {
5584                     final boolean isDep = app.pkgDeps != null
5585                             && app.pkgDeps.contains(packageName);
5586                     if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5587                         continue;
5588                     }
5589                     if (userId != UserHandle.USER_ALL && app.userId != userId) {
5590                         continue;
5591                     }
5592                     if (!app.pkgList.containsKey(packageName) && !isDep) {
5593                         continue;
5594                     }
5595                 }
5596
5597                 // Process has passed all conditions, kill it!
5598                 if (!doit) {
5599                     return true;
5600                 }
5601                 app.removed = true;
5602                 procs.add(app);
5603             }
5604         }
5605
5606         int N = procs.size();
5607         for (int i=0; i<N; i++) {
5608             removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5609         }
5610         updateOomAdjLocked();
5611         return N > 0;
5612     }
5613
5614     private void cleanupDisabledPackageComponentsLocked(
5615             String packageName, int userId, boolean killProcess, String[] changedClasses) {
5616
5617         Set<String> disabledClasses = null;
5618         boolean packageDisabled = false;
5619         IPackageManager pm = AppGlobals.getPackageManager();
5620
5621         if (changedClasses == null) {
5622             // Nothing changed...
5623             return;
5624         }
5625
5626         // Determine enable/disable state of the package and its components.
5627         int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5628         for (int i = changedClasses.length - 1; i >= 0; i--) {
5629             final String changedClass = changedClasses[i];
5630
5631             if (changedClass.equals(packageName)) {
5632                 try {
5633                     // Entire package setting changed
5634                     enabled = pm.getApplicationEnabledSetting(packageName,
5635                             (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_OWNER);
5636                 } catch (Exception e) {
5637                     // No such package/component; probably racing with uninstall.  In any
5638                     // event it means we have nothing further to do here.
5639                     return;
5640                 }
5641                 packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5642                         && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5643                 if (packageDisabled) {
5644                     // Entire package is disabled.
5645                     // No need to continue to check component states.
5646                     disabledClasses = null;
5647                     break;
5648                 }
5649             } else {
5650                 try {
5651                     enabled = pm.getComponentEnabledSetting(
5652                             new ComponentName(packageName, changedClass),
5653                             (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_OWNER);
5654                 } catch (Exception e) {
5655                     // As above, probably racing with uninstall.
5656                     return;
5657                 }
5658                 if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5659                         && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
5660                     if (disabledClasses == null) {
5661                         disabledClasses = new ArraySet<>(changedClasses.length);
5662                     }
5663                     disabledClasses.add(changedClass);
5664                 }
5665             }
5666         }
5667
5668         if (!packageDisabled && disabledClasses == null) {
5669             // Nothing to do here...
5670             return;
5671         }
5672
5673         // Clean-up disabled activities.
5674         if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
5675                 packageName, disabledClasses, true, false, userId) && mBooted) {
5676             mStackSupervisor.resumeTopActivitiesLocked();
5677             mStackSupervisor.scheduleIdleLocked();
5678         }
5679
5680         // Clean-up disabled tasks
5681         cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
5682
5683         // Clean-up disabled services.
5684         mServices.bringDownDisabledPackageServicesLocked(
5685                 packageName, disabledClasses, userId, false, killProcess, true);
5686
5687         // Clean-up disabled providers.
5688         ArrayList<ContentProviderRecord> providers = new ArrayList<>();
5689         mProviderMap.collectPackageProvidersLocked(
5690                 packageName, disabledClasses, true, false, userId, providers);
5691         for (int i = providers.size() - 1; i >= 0; i--) {
5692             removeDyingProviderLocked(null, providers.get(i), true);
5693         }
5694
5695         // Clean-up disabled broadcast receivers.
5696         for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
5697             mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
5698                     packageName, disabledClasses, userId, true);
5699         }
5700
5701     }
5702
5703     private final boolean forceStopPackageLocked(String packageName, int appId,
5704             boolean callerWillRestart, boolean purgeCache, boolean doit,
5705             boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5706         int i;
5707
5708         if (userId == UserHandle.USER_ALL && packageName == null) {
5709             Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5710         }
5711
5712         if (appId < 0 && packageName != null) {
5713             try {
5714                 appId = UserHandle.getAppId(
5715                         AppGlobals.getPackageManager().getPackageUid(packageName, 0));
5716             } catch (RemoteException e) {
5717             }
5718         }
5719
5720         if (doit) {
5721             if (packageName != null) {
5722                 Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
5723                         + " user=" + userId + ": " + reason);
5724             } else {
5725                 Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5726             }
5727
5728             final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5729             for (int ip = pmap.size() - 1; ip >= 0; ip--) {
5730                 SparseArray<Long> ba = pmap.valueAt(ip);
5731                 for (i = ba.size() - 1; i >= 0; i--) {
5732                     boolean remove = false;
5733                     final int entUid = ba.keyAt(i);
5734                     if (packageName != null) {
5735                         if (userId == UserHandle.USER_ALL) {
5736                             if (UserHandle.getAppId(entUid) == appId) {
5737                                 remove = true;
5738                             }
5739                         } else {
5740                             if (entUid == UserHandle.getUid(userId, appId)) {
5741                                 remove = true;
5742                             }
5743                         }
5744                     } else if (UserHandle.getUserId(entUid) == userId) {
5745                         remove = true;
5746                     }
5747                     if (remove) {
5748                         ba.removeAt(i);
5749                     }
5750                 }
5751                 if (ba.size() == 0) {
5752                     pmap.removeAt(ip);
5753                 }
5754             }
5755         }
5756
5757         boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
5758                 -100, callerWillRestart, true, doit, evenPersistent,
5759                 packageName == null ? ("stop user " + userId) : ("stop " + packageName));
5760
5761         if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
5762                 packageName, null, doit, evenPersistent, userId)) {
5763             if (!doit) {
5764                 return true;
5765             }
5766             didSomething = true;
5767         }
5768
5769         if (mServices.bringDownDisabledPackageServicesLocked(
5770                 packageName, null, userId, evenPersistent, true, doit)) {
5771             if (!doit) {
5772                 return true;
5773             }
5774             didSomething = true;
5775         }
5776
5777         if (packageName == null) {
5778             // Remove all sticky broadcasts from this user.
5779             mStickyBroadcasts.remove(userId);
5780         }
5781
5782         ArrayList<ContentProviderRecord> providers = new ArrayList<>();
5783         if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
5784                 userId, providers)) {
5785             if (!doit) {
5786                 return true;
5787             }
5788             didSomething = true;
5789         }
5790         for (i = providers.size() - 1; i >= 0; i--) {
5791             removeDyingProviderLocked(null, providers.get(i), true);
5792         }
5793
5794         // Remove transient permissions granted from/to this package/user
5795         removeUriPermissionsForPackageLocked(packageName, userId, false);
5796
5797         if (doit) {
5798             for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
5799                 didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
5800                         packageName, null, userId, doit);
5801             }
5802         }
5803
5804         if (packageName == null || uninstalling) {
5805             // Remove pending intents.  For now we only do this when force
5806             // stopping users, because we have some problems when doing this
5807             // for packages -- app widgets are not currently cleaned up for
5808             // such packages, so they can be left with bad pending intents.
5809             if (mIntentSenderRecords.size() > 0) {
5810                 Iterator<WeakReference<PendingIntentRecord>> it
5811                         = mIntentSenderRecords.values().iterator();
5812                 while (it.hasNext()) {
5813                     WeakReference<PendingIntentRecord> wpir = it.next();
5814                     if (wpir == null) {
5815                         it.remove();
5816                         continue;
5817                     }
5818                     PendingIntentRecord pir = wpir.get();
5819                     if (pir == null) {
5820                         it.remove();
5821                         continue;
5822                     }
5823                     if (packageName == null) {
5824                         // Stopping user, remove all objects for the user.
5825                         if (pir.key.userId != userId) {
5826                             // Not the same user, skip it.
5827                             continue;
5828                         }
5829                     } else {
5830                         if (UserHandle.getAppId(pir.uid) != appId) {
5831                             // Different app id, skip it.
5832                             continue;
5833                         }
5834                         if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5835                             // Different user, skip it.
5836                             continue;
5837                         }
5838                         if (!pir.key.packageName.equals(packageName)) {
5839                             // Different package, skip it.
5840                             continue;
5841                         }
5842                     }
5843                     if (!doit) {
5844                         return true;
5845                     }
5846                     didSomething = true;
5847                     it.remove();
5848                     pir.canceled = true;
5849                     if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
5850                         pir.key.activity.pendingResults.remove(pir.ref);
5851                     }
5852                 }
5853             }
5854         }
5855
5856         if (doit) {
5857             if (purgeCache && packageName != null) {
5858                 AttributeCache ac = AttributeCache.instance();
5859                 if (ac != null) {
5860                     ac.removePackage(packageName);
5861                 }
5862             }
5863             if (mBooted) {
5864                 mStackSupervisor.resumeTopActivitiesLocked();
5865                 mStackSupervisor.scheduleIdleLocked();
5866             }
5867         }
5868
5869         return didSomething;
5870     }
5871
5872     private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
5873         ProcessRecord old = mProcessNames.remove(name, uid);
5874         if (old != null) {
5875             old.uidRecord.numProcs--;
5876             if (old.uidRecord.numProcs == 0) {
5877                 // No more processes using this uid, tell clients it is gone.
5878                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
5879                         "No more processes in " + old.uidRecord);
5880                 enqueueUidChangeLocked(old.uidRecord, true);
5881                 mActiveUids.remove(uid);
5882             }
5883             old.uidRecord = null;
5884         }
5885         mIsolatedProcesses.remove(uid);
5886         return old;
5887     }
5888
5889     private final void addProcessNameLocked(ProcessRecord proc) {
5890         // We shouldn't already have a process under this name, but just in case we
5891         // need to clean up whatever may be there now.
5892         ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
5893         if (old == proc && proc.persistent) {
5894             // We are re-adding a persistent process.  Whatevs!  Just leave it there.
5895             Slog.w(TAG, "Re-adding persistent process " + proc);
5896         } else if (old != null) {
5897             Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
5898         }
5899         UidRecord uidRec = mActiveUids.get(proc.uid);
5900         if (uidRec == null) {
5901             uidRec = new UidRecord(proc.uid);
5902             // This is the first appearance of the uid, report it now!
5903             if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
5904                     "Creating new process uid: " + uidRec);
5905             mActiveUids.put(proc.uid, uidRec);
5906             enqueueUidChangeLocked(uidRec, false);
5907         }
5908         proc.uidRecord = uidRec;
5909         uidRec.numProcs++;
5910         mProcessNames.put(proc.processName, proc.uid, proc);
5911         if (proc.isolated) {
5912             mIsolatedProcesses.put(proc.uid, proc);
5913         }
5914     }
5915
5916     private final boolean removeProcessLocked(ProcessRecord app,
5917             boolean callerWillRestart, boolean allowRestart, String reason) {
5918         final String name = app.processName;
5919         final int uid = app.uid;
5920         if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
5921             "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
5922
5923         removeProcessNameLocked(name, uid);
5924         if (mHeavyWeightProcess == app) {
5925             mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5926                     mHeavyWeightProcess.userId, 0));
5927             mHeavyWeightProcess = null;
5928         }
5929         boolean needRestart = false;
5930         if (app.pid > 0 && app.pid != MY_PID) {
5931             int pid = app.pid;
5932             synchronized (mPidsSelfLocked) {
5933                 mPidsSelfLocked.remove(pid);
5934                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5935             }
5936             mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5937             if (app.isolated) {
5938                 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5939             }
5940             boolean willRestart = false;
5941             if (app.persistent && !app.isolated) {
5942                 if (!callerWillRestart) {
5943                     willRestart = true;
5944                 } else {
5945                     needRestart = true;
5946                 }
5947             }
5948             app.kill(reason, true);
5949             handleAppDiedLocked(app, willRestart, allowRestart);
5950             if (willRestart) {
5951                 removeLruProcessLocked(app);
5952                 addAppLocked(app.info, false, null /* ABI override */);
5953             }
5954         } else {
5955             mRemovedProcesses.add(app);
5956         }
5957
5958         return needRestart;
5959     }
5960
5961     private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
5962         cleanupAppInLaunchingProvidersLocked(app, true);
5963         removeProcessLocked(app, false, true, "timeout publishing content providers");
5964     }
5965
5966     private final void processStartTimedOutLocked(ProcessRecord app) {
5967         final int pid = app.pid;
5968         boolean gone = false;
5969         synchronized (mPidsSelfLocked) {
5970             ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5971             if (knownApp != null && knownApp.thread == null) {
5972                 mPidsSelfLocked.remove(pid);
5973                 gone = true;
5974             }
5975         }
5976
5977         if (gone) {
5978             Slog.w(TAG, "Process " + app + " failed to attach");
5979             EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5980                     pid, app.uid, app.processName);
5981             removeProcessNameLocked(app.processName, app.uid);
5982             if (mHeavyWeightProcess == app) {
5983                 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5984                         mHeavyWeightProcess.userId, 0));
5985                 mHeavyWeightProcess = null;
5986             }
5987             mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5988             if (app.isolated) {
5989                 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5990             }
5991             // Take care of any launching providers waiting for this process.
5992             cleanupAppInLaunchingProvidersLocked(app, true);
5993             // Take care of any services that are waiting for the process.
5994             mServices.processStartTimedOutLocked(app);
5995             app.kill("start timeout", true);
5996             removeLruProcessLocked(app);
5997             if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5998                 Slog.w(TAG, "Unattached app died before backup, skipping");
5999                 try {
6000                     IBackupManager bm = IBackupManager.Stub.asInterface(
6001                             ServiceManager.getService(Context.BACKUP_SERVICE));
6002                     bm.agentDisconnected(app.info.packageName);
6003                 } catch (RemoteException e) {
6004                     // Can't happen; the backup manager is local
6005                 }
6006             }
6007             if (isPendingBroadcastProcessLocked(pid)) {
6008                 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6009                 skipPendingBroadcastLocked(pid);
6010             }
6011         } else {
6012             Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6013         }
6014     }
6015
6016     private final boolean attachApplicationLocked(IApplicationThread thread,
6017             int pid) {
6018
6019         // Find the application record that is being attached...  either via
6020         // the pid if we are running in multiple processes, or just pull the
6021         // next app record if we are emulating process with anonymous threads.
6022         ProcessRecord app;
6023         if (pid != MY_PID && pid >= 0) {
6024             synchronized (mPidsSelfLocked) {
6025                 app = mPidsSelfLocked.get(pid);
6026             }
6027         } else {
6028             app = null;
6029         }
6030
6031         if (app == null) {
6032             Slog.w(TAG, "No pending application record for pid " + pid
6033                     + " (IApplicationThread " + thread + "); dropping process");
6034             EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6035             if (pid > 0 && pid != MY_PID) {
6036                 Process.killProcessQuiet(pid);
6037                 //TODO: killProcessGroup(app.info.uid, pid);
6038             } else {
6039                 try {
6040                     thread.scheduleExit();
6041                 } catch (Exception e) {
6042                     // Ignore exceptions.
6043                 }
6044             }
6045             return false;
6046         }
6047
6048         // If this application record is still attached to a previous
6049         // process, clean it up now.
6050         if (app.thread != null) {
6051             handleAppDiedLocked(app, true, true);
6052         }
6053
6054         // Tell the process all about itself.
6055
6056         if (DEBUG_ALL) Slog.v(
6057                 TAG, "Binding process pid " + pid + " to record " + app);
6058
6059         final String processName = app.processName;
6060         try {
6061             AppDeathRecipient adr = new AppDeathRecipient(
6062                     app, pid, thread);
6063             thread.asBinder().linkToDeath(adr, 0);
6064             app.deathRecipient = adr;
6065         } catch (RemoteException e) {
6066             app.resetPackageList(mProcessStats);
6067             startProcessLocked(app, "link fail", processName);
6068             return false;
6069         }
6070
6071         EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6072
6073         app.makeActive(thread, mProcessStats);
6074         app.curAdj = app.setAdj = -100;
6075         app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
6076         app.forcingToForeground = null;
6077         updateProcessForegroundLocked(app, false, false);
6078         app.hasShownUi = false;
6079         app.debugging = false;
6080         app.cached = false;
6081         app.killedByAm = false;
6082
6083         mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6084
6085         boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6086         List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6087
6088         if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
6089             Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
6090             msg.obj = app;
6091             mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
6092         }
6093
6094         if (!normalMode) {
6095             Slog.i(TAG, "Launching preboot mode app: " + app);
6096         }
6097
6098         if (DEBUG_ALL) Slog.v(
6099             TAG, "New app record " + app
6100             + " thread=" + thread.asBinder() + " pid=" + pid);
6101         try {
6102             int testMode = IApplicationThread.DEBUG_OFF;
6103             if (mDebugApp != null && mDebugApp.equals(processName)) {
6104                 testMode = mWaitForDebugger
6105                     ? IApplicationThread.DEBUG_WAIT
6106                     : IApplicationThread.DEBUG_ON;
6107                 app.debugging = true;
6108                 if (mDebugTransient) {
6109                     mDebugApp = mOrigDebugApp;
6110                     mWaitForDebugger = mOrigWaitForDebugger;
6111                 }
6112             }
6113             String profileFile = app.instrumentationProfileFile;
6114             ParcelFileDescriptor profileFd = null;
6115             int samplingInterval = 0;
6116             boolean profileAutoStop = false;
6117             if (mProfileApp != null && mProfileApp.equals(processName)) {
6118                 mProfileProc = app;
6119                 profileFile = mProfileFile;
6120                 profileFd = mProfileFd;
6121                 samplingInterval = mSamplingInterval;
6122                 profileAutoStop = mAutoStopProfiler;
6123             }
6124             boolean enableOpenGlTrace = false;
6125             if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
6126                 enableOpenGlTrace = true;
6127                 mOpenGlTraceApp = null;
6128             }
6129
6130             // If the app is being launched for restore or full backup, set it up specially
6131             boolean isRestrictedBackupMode = false;
6132             if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6133                 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
6134                         || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6135                         || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
6136             }
6137
6138             ensurePackageDexOpt(app.instrumentationInfo != null
6139                     ? app.instrumentationInfo.packageName
6140                     : app.info.packageName);
6141             if (app.instrumentationClass != null) {
6142                 ensurePackageDexOpt(app.instrumentationClass.getPackageName());
6143             }
6144             if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
6145                     + processName + " with config " + mConfiguration);
6146             ApplicationInfo appInfo = app.instrumentationInfo != null
6147                     ? app.instrumentationInfo : app.info;
6148             app.compat = compatibilityInfoForPackageLocked(appInfo);
6149             if (profileFd != null) {
6150                 profileFd = profileFd.dup();
6151             }
6152             ProfilerInfo profilerInfo = profileFile == null ? null
6153                     : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6154             thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6155                     profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6156                     app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
6157                     isRestrictedBackupMode || !normalMode, app.persistent,
6158                     new Configuration(mConfiguration), app.compat,
6159                     getCommonServicesLocked(app.isolated),
6160                     mCoreSettingsObserver.getCoreSettingsLocked());
6161             updateLruProcessLocked(app, false, null);
6162             app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6163         } catch (Exception e) {
6164             // todo: Yikes!  What should we do?  For now we will try to
6165             // start another process, but that could easily get us in
6166             // an infinite loop of restarting processes...
6167             Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6168
6169             app.resetPackageList(mProcessStats);
6170             app.unlinkDeathRecipient();
6171             startProcessLocked(app, "bind fail", processName);
6172             return false;
6173         }
6174
6175         // Remove this record from the list of starting applications.
6176         mPersistentStartingProcesses.remove(app);
6177         if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
6178                 "Attach application locked removing on hold: " + app);
6179         mProcessesOnHold.remove(app);
6180
6181         boolean badApp = false;
6182         boolean didSomething = false;
6183
6184         // See if the top visible activity is waiting to run in this process...
6185         if (normalMode) {
6186             try {
6187                 if (mStackSupervisor.attachApplicationLocked(app)) {
6188                     didSomething = true;
6189                 }
6190             } catch (Exception e) {
6191                 Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6192                 badApp = true;
6193             }
6194         }
6195
6196         // Find any services that should be running in this process...
6197         if (!badApp) {
6198             try {
6199                 didSomething |= mServices.attachApplicationLocked(app, processName);
6200             } catch (Exception e) {
6201                 Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6202                 badApp = true;
6203             }
6204         }
6205
6206         // Check if a next-broadcast receiver is in this process...
6207         if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6208             try {
6209                 didSomething |= sendPendingBroadcastsLocked(app);
6210             } catch (Exception e) {
6211                 // If the app died trying to launch the receiver we declare it 'bad'
6212                 Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6213                 badApp = true;
6214             }
6215         }
6216
6217         // Check whether the next backup agent is in this process...
6218         if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6219             if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
6220                     "New app is backup target, launching agent for " + app);
6221             ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
6222             try {
6223                 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6224                         compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6225                         mBackupTarget.backupMode);
6226             } catch (Exception e) {
6227                 Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6228                 badApp = true;
6229             }
6230         }
6231
6232         if (badApp) {
6233             app.kill("error during init", true);
6234             handleAppDiedLocked(app, false, true);
6235             return false;
6236         }
6237
6238         if (!didSomething) {
6239             updateOomAdjLocked();
6240         }
6241
6242         return true;
6243     }
6244
6245     @Override
6246     public final void attachApplication(IApplicationThread thread) {
6247         synchronized (this) {
6248             int callingPid = Binder.getCallingPid();
6249             final long origId = Binder.clearCallingIdentity();
6250             attachApplicationLocked(thread, callingPid);
6251             Binder.restoreCallingIdentity(origId);
6252         }
6253     }
6254
6255     @Override
6256     public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6257         final long origId = Binder.clearCallingIdentity();
6258         synchronized (this) {
6259             ActivityStack stack = ActivityRecord.getStackLocked(token);
6260             if (stack != null) {
6261                 ActivityRecord r =
6262                         mStackSupervisor.activityIdleInternalLocked(token, false, config);
6263                 if (stopProfiling) {
6264                     if ((mProfileProc == r.app) && (mProfileFd != null)) {
6265                         try {
6266                             mProfileFd.close();
6267                         } catch (IOException e) {
6268                         }
6269                         clearProfilerLocked();
6270                     }
6271                 }
6272             }
6273         }
6274         Binder.restoreCallingIdentity(origId);
6275     }
6276
6277     void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6278         mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6279                 finishBooting ? 1 : 0, enableScreen ? 1 : 0));
6280     }
6281
6282     void enableScreenAfterBoot() {
6283         EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6284                 SystemClock.uptimeMillis());
6285         mWindowManager.enableScreenAfterBoot();
6286
6287         synchronized (this) {
6288             updateEventDispatchingLocked();
6289         }
6290     }
6291
6292     @Override
6293     public void showBootMessage(final CharSequence msg, final boolean always) {
6294         if (Binder.getCallingUid() != Process.myUid()) {
6295             // These days only the core system can call this, so apps can't get in
6296             // the way of what we show about running them.
6297         }
6298         mWindowManager.showBootMessage(msg, always);
6299     }
6300
6301     @Override
6302     public void keyguardWaitingForActivityDrawn() {
6303         enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6304         final long token = Binder.clearCallingIdentity();
6305         try {
6306             synchronized (this) {
6307                 if (DEBUG_LOCKSCREEN) logLockScreen("");
6308                 mWindowManager.keyguardWaitingForActivityDrawn();
6309                 if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6310                     mLockScreenShown = LOCK_SCREEN_LEAVING;
6311                     updateSleepIfNeededLocked();
6312                 }
6313             }
6314         } finally {
6315             Binder.restoreCallingIdentity(token);
6316         }
6317     }
6318
6319     @Override
6320     public void keyguardGoingAway(boolean disableWindowAnimations,
6321             boolean keyguardGoingToNotificationShade) {
6322         enforceNotIsolatedCaller("keyguardGoingAway");
6323         final long token = Binder.clearCallingIdentity();
6324         try {
6325             synchronized (this) {
6326                 if (DEBUG_LOCKSCREEN) logLockScreen("");
6327                 mWindowManager.keyguardGoingAway(disableWindowAnimations,
6328                         keyguardGoingToNotificationShade);
6329                 if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6330                     mLockScreenShown = LOCK_SCREEN_HIDDEN;
6331                     updateSleepIfNeededLocked();
6332                 }
6333             }
6334         } finally {
6335             Binder.restoreCallingIdentity(token);
6336         }
6337     }
6338
6339     final void finishBooting() {
6340         synchronized (this) {
6341             if (!mBootAnimationComplete) {
6342                 mCallFinishBooting = true;
6343                 return;
6344             }
6345             mCallFinishBooting = false;
6346         }
6347
6348         ArraySet<String> completedIsas = new ArraySet<String>();
6349         for (String abi : Build.SUPPORTED_ABIS) {
6350             Process.establishZygoteConnectionForAbi(abi);
6351             final String instructionSet = VMRuntime.getInstructionSet(abi);
6352             if (!completedIsas.contains(instructionSet)) {
6353                 if (mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi)) != 0) {
6354                     Slog.e(TAG, "Unable to mark boot complete for abi: " + abi);
6355                 }
6356                 completedIsas.add(instructionSet);
6357             }
6358         }
6359
6360         IntentFilter pkgFilter = new IntentFilter();
6361         pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6362         pkgFilter.addDataScheme("package");
6363         mContext.registerReceiver(new BroadcastReceiver() {
6364             @Override
6365             public void onReceive(Context context, Intent intent) {
6366                 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6367                 if (pkgs != null) {
6368                     for (String pkg : pkgs) {
6369                         synchronized (ActivityManagerService.this) {
6370                             if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6371                                     0, "query restart")) {
6372                                 setResultCode(Activity.RESULT_OK);
6373                                 return;
6374                             }
6375                         }
6376                     }
6377                 }
6378             }
6379         }, pkgFilter);
6380
6381         IntentFilter dumpheapFilter = new IntentFilter();
6382         dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
6383         mContext.registerReceiver(new BroadcastReceiver() {
6384             @Override
6385             public void onReceive(Context context, Intent intent) {
6386                 if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
6387                     mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
6388                 } else {
6389                     mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
6390                 }
6391             }
6392         }, dumpheapFilter);
6393
6394         // Let system services know.
6395         mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6396
6397         synchronized (this) {
6398             // Ensure that any processes we had put on hold are now started
6399             // up.
6400             final int NP = mProcessesOnHold.size();
6401             if (NP > 0) {
6402                 ArrayList<ProcessRecord> procs =
6403                     new ArrayList<ProcessRecord>(mProcessesOnHold);
6404                 for (int ip=0; ip<NP; ip++) {
6405                     if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
6406                             + procs.get(ip));
6407                     startProcessLocked(procs.get(ip), "on-hold", null);
6408                 }
6409             }
6410
6411             if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6412                 // Start looking for apps that are abusing wake locks.
6413                 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6414                 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6415                 // Tell anyone interested that we are done booting!
6416                 SystemProperties.set("sys.boot_completed", "1");
6417
6418                 // And trigger dev.bootcomplete if we are not showing encryption progress
6419                 if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6420                     || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6421                     SystemProperties.set("dev.bootcomplete", "1");
6422                 }
6423                 for (int i=0; i<mStartedUsers.size(); i++) {
6424                     UserState uss = mStartedUsers.valueAt(i);
6425                     if (uss.mState == UserState.STATE_BOOTING) {
6426                         uss.mState = UserState.STATE_RUNNING;
6427                         final int userId = mStartedUsers.keyAt(i);
6428                         Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
6429                         intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
6430                         intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
6431                         broadcastIntentLocked(null, null, intent, null,
6432                                 new IIntentReceiver.Stub() {
6433                                     @Override
6434                                     public void performReceive(Intent intent, int resultCode,
6435                                             String data, Bundle extras, boolean ordered,
6436                                             boolean sticky, int sendingUser) {
6437                                         synchronized (ActivityManagerService.this) {
6438                                             requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6439                                                     true, false);
6440                                         }
6441                                     }
6442                                 },
6443                                 0, null, null,
6444                                 new String[] {android.Manifest.permission.RECEIVE_BOOT_COMPLETED},
6445                                 AppOpsManager.OP_NONE, null, true, false,
6446                                 MY_PID, Process.SYSTEM_UID, userId);
6447                     }
6448                 }
6449                 scheduleStartProfilesLocked();
6450             }
6451         }
6452     }
6453
6454     @Override
6455     public void bootAnimationComplete() {
6456         final boolean callFinishBooting;
6457         synchronized (this) {
6458             callFinishBooting = mCallFinishBooting;
6459             mBootAnimationComplete = true;
6460         }
6461         if (callFinishBooting) {
6462             finishBooting();
6463         }
6464     }
6465
6466     final void ensureBootCompleted() {
6467         boolean booting;
6468         boolean enableScreen;
6469         synchronized (this) {
6470             booting = mBooting;
6471             mBooting = false;
6472             enableScreen = !mBooted;
6473             mBooted = true;
6474         }
6475
6476         if (booting) {
6477             finishBooting();
6478         }
6479
6480         if (enableScreen) {
6481             enableScreenAfterBoot();
6482         }
6483     }
6484
6485     @Override
6486     public final void activityResumed(IBinder token) {
6487         final long origId = Binder.clearCallingIdentity();
6488         synchronized(this) {
6489             ActivityStack stack = ActivityRecord.getStackLocked(token);
6490             if (stack != null) {
6491                 ActivityRecord.activityResumedLocked(token);
6492             }
6493         }
6494         Binder.restoreCallingIdentity(origId);
6495     }
6496
6497     @Override
6498     public final void activityPaused(IBinder token) {
6499         final long origId = Binder.clearCallingIdentity();
6500         synchronized(this) {
6501             ActivityStack stack = ActivityRecord.getStackLocked(token);
6502             if (stack != null) {
6503                 stack.activityPausedLocked(token, false);
6504             }
6505         }
6506         Binder.restoreCallingIdentity(origId);
6507     }
6508
6509     @Override
6510     public final void activityStopped(IBinder token, Bundle icicle,
6511             PersistableBundle persistentState, CharSequence description) {
6512         if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
6513
6514         // Refuse possible leaked file descriptors
6515         if (icicle != null && icicle.hasFileDescriptors()) {
6516             throw new IllegalArgumentException("File descriptors passed in Bundle");
6517         }
6518
6519         final long origId = Binder.clearCallingIdentity();
6520
6521         synchronized (this) {
6522             ActivityRecord r = ActivityRecord.isInStackLocked(token);
6523             if (r != null) {
6524                 r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6525             }
6526         }
6527
6528         trimApplications();
6529
6530         Binder.restoreCallingIdentity(origId);
6531     }
6532
6533     @Override
6534     public final void activityDestroyed(IBinder token) {
6535         if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
6536         synchronized (this) {
6537             ActivityStack stack = ActivityRecord.getStackLocked(token);
6538             if (stack != null) {
6539                 stack.activityDestroyedLocked(token, "activityDestroyed");
6540             }
6541         }
6542     }
6543
6544     @Override
6545     public final void backgroundResourcesReleased(IBinder token) {
6546         final long origId = Binder.clearCallingIdentity();
6547         try {
6548             synchronized (this) {
6549                 ActivityStack stack = ActivityRecord.getStackLocked(token);
6550                 if (stack != null) {
6551                     stack.backgroundResourcesReleased();
6552                 }
6553             }
6554         } finally {
6555             Binder.restoreCallingIdentity(origId);
6556         }
6557     }
6558
6559     @Override
6560     public final void notifyLaunchTaskBehindComplete(IBinder token) {
6561         mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6562     }
6563
6564     @Override
6565     public final void notifyEnterAnimationComplete(IBinder token) {
6566         mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6567     }
6568
6569     @Override
6570     public String getCallingPackage(IBinder token) {
6571         synchronized (this) {
6572             ActivityRecord r = getCallingRecordLocked(token);
6573             return r != null ? r.info.packageName : null;
6574         }
6575     }
6576
6577     @Override
6578     public ComponentName getCallingActivity(IBinder token) {
6579         synchronized (this) {
6580             ActivityRecord r = getCallingRecordLocked(token);
6581             return r != null ? r.intent.getComponent() : null;
6582         }
6583     }
6584
6585     private ActivityRecord getCallingRecordLocked(IBinder token) {
6586         ActivityRecord r = ActivityRecord.isInStackLocked(token);
6587         if (r == null) {
6588             return null;
6589         }
6590         return r.resultTo;
6591     }
6592
6593     @Override
6594     public ComponentName getActivityClassForToken(IBinder token) {
6595         synchronized(this) {
6596             ActivityRecord r = ActivityRecord.isInStackLocked(token);
6597             if (r == null) {
6598                 return null;
6599             }
6600             return r.intent.getComponent();
6601         }
6602     }
6603
6604     @Override
6605     public String getPackageForToken(IBinder token) {
6606         synchronized(this) {
6607             ActivityRecord r = ActivityRecord.isInStackLocked(token);
6608             if (r == null) {
6609                 return null;
6610             }
6611             return r.packageName;
6612         }
6613     }
6614
6615     @Override
6616     public boolean isRootVoiceInteraction(IBinder token) {
6617         synchronized(this) {
6618             ActivityRecord r = ActivityRecord.isInStackLocked(token);
6619             if (r == null) {
6620                 return false;
6621             }
6622             return r.rootVoiceInteraction;
6623         }
6624     }
6625
6626     @Override
6627     public IIntentSender getIntentSender(int type,
6628             String packageName, IBinder token, String resultWho,
6629             int requestCode, Intent[] intents, String[] resolvedTypes,
6630             int flags, Bundle options, int userId) {
6631         enforceNotIsolatedCaller("getIntentSender");
6632         // Refuse possible leaked file descriptors
6633         if (intents != null) {
6634             if (intents.length < 1) {
6635                 throw new IllegalArgumentException("Intents array length must be >= 1");
6636             }
6637             for (int i=0; i<intents.length; i++) {
6638                 Intent intent = intents[i];
6639                 if (intent != null) {
6640                     if (intent.hasFileDescriptors()) {
6641                         throw new IllegalArgumentException("File descriptors passed in Intent");
6642                     }
6643                     if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6644                             (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6645                         throw new IllegalArgumentException(
6646                                 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6647                     }
6648                     intents[i] = new Intent(intent);
6649                 }
6650             }
6651             if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6652                 throw new IllegalArgumentException(
6653                         "Intent array length does not match resolvedTypes length");
6654             }
6655         }
6656         if (options != null) {
6657             if (options.hasFileDescriptors()) {
6658                 throw new IllegalArgumentException("File descriptors passed in options");
6659             }
6660         }
6661
6662         synchronized(this) {
6663             int callingUid = Binder.getCallingUid();
6664             int origUserId = userId;
6665             userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6666                     type == ActivityManager.INTENT_SENDER_BROADCAST,
6667                     ALLOW_NON_FULL, "getIntentSender", null);
6668             if (origUserId == UserHandle.USER_CURRENT) {
6669                 // We don't want to evaluate this until the pending intent is
6670                 // actually executed.  However, we do want to always do the
6671                 // security checking for it above.
6672                 userId = UserHandle.USER_CURRENT;
6673             }
6674             try {
6675                 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6676                     int uid = AppGlobals.getPackageManager()
6677                             .getPackageUid(packageName, UserHandle.getUserId(callingUid));
6678                     if (!UserHandle.isSameApp(callingUid, uid)) {
6679                         String msg = "Permission Denial: getIntentSender() from pid="
6680                             + Binder.getCallingPid()
6681                             + ", uid=" + Binder.getCallingUid()
6682                             + ", (need uid=" + uid + ")"
6683                             + " is not allowed to send as package " + packageName;
6684                         Slog.w(TAG, msg);
6685                         throw new SecurityException(msg);
6686                     }
6687                 }
6688
6689                 return getIntentSenderLocked(type, packageName, callingUid, userId,
6690                         token, resultWho, requestCode, intents, resolvedTypes, flags, options);
6691
6692             } catch (RemoteException e) {
6693                 throw new SecurityException(e);
6694             }
6695         }
6696     }
6697
6698     IIntentSender getIntentSenderLocked(int type, String packageName,
6699             int callingUid, int userId, IBinder token, String resultWho,
6700             int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6701             Bundle options) {
6702         if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6703         ActivityRecord activity = null;
6704         if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6705             activity = ActivityRecord.isInStackLocked(token);
6706             if (activity == null) {
6707                 return null;
6708             }
6709             if (activity.finishing) {
6710                 return null;
6711             }
6712         }
6713
6714         final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6715         final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6716         final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6717         flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6718                 |PendingIntent.FLAG_UPDATE_CURRENT);
6719
6720         PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6721                 type, packageName, activity, resultWho,
6722                 requestCode, intents, resolvedTypes, flags, options, userId);
6723         WeakReference<PendingIntentRecord> ref;
6724         ref = mIntentSenderRecords.get(key);
6725         PendingIntentRecord rec = ref != null ? ref.get() : null;
6726         if (rec != null) {
6727             if (!cancelCurrent) {
6728                 if (updateCurrent) {
6729                     if (rec.key.requestIntent != null) {
6730                         rec.key.requestIntent.replaceExtras(intents != null ?
6731                                 intents[intents.length - 1] : null);
6732                     }
6733                     if (intents != null) {
6734                         intents[intents.length-1] = rec.key.requestIntent;
6735                         rec.key.allIntents = intents;
6736                         rec.key.allResolvedTypes = resolvedTypes;
6737                     } else {
6738                         rec.key.allIntents = null;
6739                         rec.key.allResolvedTypes = null;
6740                     }
6741                 }
6742                 return rec;
6743             }
6744             rec.canceled = true;
6745             mIntentSenderRecords.remove(key);
6746         }
6747         if (noCreate) {
6748             return rec;
6749         }
6750         rec = new PendingIntentRecord(this, key, callingUid);
6751         mIntentSenderRecords.put(key, rec.ref);
6752         if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6753             if (activity.pendingResults == null) {
6754                 activity.pendingResults
6755                         = new HashSet<WeakReference<PendingIntentRecord>>();
6756             }
6757             activity.pendingResults.add(rec.ref);
6758         }
6759         return rec;
6760     }
6761
6762     @Override
6763     public void cancelIntentSender(IIntentSender sender) {
6764         if (!(sender instanceof PendingIntentRecord)) {
6765             return;
6766         }
6767         synchronized(this) {
6768             PendingIntentRecord rec = (PendingIntentRecord)sender;
6769             try {
6770                 int uid = AppGlobals.getPackageManager()
6771                         .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
6772                 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6773                     String msg = "Permission Denial: cancelIntentSender() from pid="
6774                         + Binder.getCallingPid()
6775                         + ", uid=" + Binder.getCallingUid()
6776                         + " is not allowed to cancel packges "
6777                         + rec.key.packageName;
6778                     Slog.w(TAG, msg);
6779                     throw new SecurityException(msg);
6780                 }
6781             } catch (RemoteException e) {
6782                 throw new SecurityException(e);
6783             }
6784             cancelIntentSenderLocked(rec, true);
6785         }
6786     }
6787
6788     void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
6789         rec.canceled = true;
6790         mIntentSenderRecords.remove(rec.key);
6791         if (cleanActivity && rec.key.activity != null) {
6792             rec.key.activity.pendingResults.remove(rec.ref);
6793         }
6794     }
6795
6796     @Override
6797     public String getPackageForIntentSender(IIntentSender pendingResult) {
6798         if (!(pendingResult instanceof PendingIntentRecord)) {
6799             return null;
6800         }
6801         try {
6802             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6803             return res.key.packageName;
6804         } catch (ClassCastException e) {
6805         }
6806         return null;
6807     }
6808
6809     @Override
6810     public int getUidForIntentSender(IIntentSender sender) {
6811         if (sender instanceof PendingIntentRecord) {
6812             try {
6813                 PendingIntentRecord res = (PendingIntentRecord)sender;
6814                 return res.uid;
6815             } catch (ClassCastException e) {
6816             }
6817         }
6818         return -1;
6819     }
6820
6821     @Override
6822     public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
6823         if (!(pendingResult instanceof PendingIntentRecord)) {
6824             return false;
6825         }
6826         try {
6827             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6828             if (res.key.allIntents == null) {
6829                 return false;
6830             }
6831             for (int i=0; i<res.key.allIntents.length; i++) {
6832                 Intent intent = res.key.allIntents[i];
6833                 if (intent.getPackage() != null && intent.getComponent() != null) {
6834                     return false;
6835                 }
6836             }
6837             return true;
6838         } catch (ClassCastException e) {
6839         }
6840         return false;
6841     }
6842
6843     @Override
6844     public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
6845         if (!(pendingResult instanceof PendingIntentRecord)) {
6846             return false;
6847         }
6848         try {
6849             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6850             if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6851                 return true;
6852             }
6853             return false;
6854         } catch (ClassCastException e) {
6855         }
6856         return false;
6857     }
6858
6859     @Override
6860     public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6861         if (!(pendingResult instanceof PendingIntentRecord)) {
6862             return null;
6863         }
6864         try {
6865             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6866             return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6867         } catch (ClassCastException e) {
6868         }
6869         return null;
6870     }
6871
6872     @Override
6873     public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6874         if (!(pendingResult instanceof PendingIntentRecord)) {
6875             return null;
6876         }
6877         try {
6878             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6879             synchronized (this) {
6880                 return getTagForIntentSenderLocked(res, prefix);
6881             }
6882         } catch (ClassCastException e) {
6883         }
6884         return null;
6885     }
6886
6887     String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
6888         final Intent intent = res.key.requestIntent;
6889         if (intent != null) {
6890             if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6891                     || res.lastTagPrefix.equals(prefix))) {
6892                 return res.lastTag;
6893             }
6894             res.lastTagPrefix = prefix;
6895             final StringBuilder sb = new StringBuilder(128);
6896             if (prefix != null) {
6897                 sb.append(prefix);
6898             }
6899             if (intent.getAction() != null) {
6900                 sb.append(intent.getAction());
6901             } else if (intent.getComponent() != null) {
6902                 intent.getComponent().appendShortString(sb);
6903             } else {
6904                 sb.append("?");
6905             }
6906             return res.lastTag = sb.toString();
6907         }
6908         return null;
6909     }
6910
6911     @Override
6912     public void setProcessLimit(int max) {
6913         enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6914                 "setProcessLimit()");
6915         synchronized (this) {
6916             mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6917             mProcessLimitOverride = max;
6918         }
6919         trimApplications();
6920     }
6921
6922     @Override
6923     public int getProcessLimit() {
6924         synchronized (this) {
6925             return mProcessLimitOverride;
6926         }
6927     }
6928
6929     void foregroundTokenDied(ForegroundToken token) {
6930         synchronized (ActivityManagerService.this) {
6931             synchronized (mPidsSelfLocked) {
6932                 ForegroundToken cur
6933                     = mForegroundProcesses.get(token.pid);
6934                 if (cur != token) {
6935                     return;
6936                 }
6937                 mForegroundProcesses.remove(token.pid);
6938                 ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6939                 if (pr == null) {
6940                     return;
6941                 }
6942                 pr.forcingToForeground = null;
6943                 updateProcessForegroundLocked(pr, false, false);
6944             }
6945             updateOomAdjLocked();
6946         }
6947     }
6948
6949     @Override
6950     public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6951         enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6952                 "setProcessForeground()");
6953         synchronized(this) {
6954             boolean changed = false;
6955
6956             synchronized (mPidsSelfLocked) {
6957                 ProcessRecord pr = mPidsSelfLocked.get(pid);
6958                 if (pr == null && isForeground) {
6959                     Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6960                     return;
6961                 }
6962                 ForegroundToken oldToken = mForegroundProcesses.get(pid);
6963                 if (oldToken != null) {
6964                     oldToken.token.unlinkToDeath(oldToken, 0);
6965                     mForegroundProcesses.remove(pid);
6966                     if (pr != null) {
6967                         pr.forcingToForeground = null;
6968                     }
6969                     changed = true;
6970                 }
6971                 if (isForeground && token != null) {
6972                     ForegroundToken newToken = new ForegroundToken() {
6973                         @Override
6974                         public void binderDied() {
6975                             foregroundTokenDied(this);
6976                         }
6977                     };
6978                     newToken.pid = pid;
6979                     newToken.token = token;
6980                     try {
6981                         token.linkToDeath(newToken, 0);
6982                         mForegroundProcesses.put(pid, newToken);
6983                         pr.forcingToForeground = token;
6984                         changed = true;
6985                     } catch (RemoteException e) {
6986                         // If the process died while doing this, we will later
6987                         // do the cleanup with the process death link.
6988                     }
6989                 }
6990             }
6991
6992             if (changed) {
6993                 updateOomAdjLocked();
6994             }
6995         }
6996     }
6997
6998     // =========================================================
6999     // PROCESS INFO
7000     // =========================================================
7001
7002     static class ProcessInfoService extends IProcessInfoService.Stub {
7003         final ActivityManagerService mActivityManagerService;
7004         ProcessInfoService(ActivityManagerService activityManagerService) {
7005             mActivityManagerService = activityManagerService;
7006         }
7007
7008         @Override
7009         public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
7010             mActivityManagerService.getProcessStatesForPIDs(/*in*/ pids, /*out*/ states);
7011         }
7012     }
7013
7014     /**
7015      * For each PID in the given input array, write the current process state
7016      * for that process into the output array, or -1 to indicate that no
7017      * process with the given PID exists.
7018      */
7019     public void getProcessStatesForPIDs(/*in*/ int[] pids, /*out*/ int[] states) {
7020         if (pids == null) {
7021             throw new NullPointerException("pids");
7022         } else if (states == null) {
7023             throw new NullPointerException("states");
7024         } else if (pids.length != states.length) {
7025             throw new IllegalArgumentException("input and output arrays have different lengths!");
7026         }
7027
7028         synchronized (mPidsSelfLocked) {
7029             for (int i = 0; i < pids.length; i++) {
7030                 ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
7031                 states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
7032                         pr.curProcState;
7033             }
7034         }
7035     }
7036
7037     // =========================================================
7038     // PERMISSIONS
7039     // =========================================================
7040
7041     static class PermissionController extends IPermissionController.Stub {
7042         ActivityManagerService mActivityManagerService;
7043         PermissionController(ActivityManagerService activityManagerService) {
7044             mActivityManagerService = activityManagerService;
7045         }
7046
7047         @Override
7048         public boolean checkPermission(String permission, int pid, int uid) {
7049             return mActivityManagerService.checkPermission(permission, pid,
7050                     uid) == PackageManager.PERMISSION_GRANTED;
7051         }
7052
7053         @Override
7054         public String[] getPackagesForUid(int uid) {
7055             return mActivityManagerService.mContext.getPackageManager()
7056                     .getPackagesForUid(uid);
7057         }
7058
7059         @Override
7060         public boolean isRuntimePermission(String permission) {
7061             try {
7062                 PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
7063                         .getPermissionInfo(permission, 0);
7064                 return info.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS;
7065             } catch (NameNotFoundException nnfe) {
7066                 Slog.e(TAG, "No such permission: "+ permission, nnfe);
7067             }
7068             return false;
7069         }
7070     }
7071
7072     class IntentFirewallInterface implements IntentFirewall.AMSInterface {
7073         @Override
7074         public int checkComponentPermission(String permission, int pid, int uid,
7075                 int owningUid, boolean exported) {
7076             return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
7077                     owningUid, exported);
7078         }
7079
7080         @Override
7081         public Object getAMSLock() {
7082             return ActivityManagerService.this;
7083         }
7084     }
7085
7086     /**
7087      * This can be called with or without the global lock held.
7088      */
7089     int checkComponentPermission(String permission, int pid, int uid,
7090             int owningUid, boolean exported) {
7091         if (pid == MY_PID) {
7092             return PackageManager.PERMISSION_GRANTED;
7093         }
7094         return ActivityManager.checkComponentPermission(permission, uid,
7095                 owningUid, exported);
7096     }
7097
7098     /**
7099      * As the only public entry point for permissions checking, this method
7100      * can enforce the semantic that requesting a check on a null global
7101      * permission is automatically denied.  (Internally a null permission
7102      * string is used when calling {@link #checkComponentPermission} in cases
7103      * when only uid-based security is needed.)
7104      *
7105      * This can be called with or without the global lock held.
7106      */
7107     @Override
7108     public int checkPermission(String permission, int pid, int uid) {
7109         if (permission == null) {
7110             return PackageManager.PERMISSION_DENIED;
7111         }
7112         return checkComponentPermission(permission, pid, uid, -1, true);
7113     }
7114
7115     @Override
7116     public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
7117         if (permission == null) {
7118             return PackageManager.PERMISSION_DENIED;
7119         }
7120
7121         // We might be performing an operation on behalf of an indirect binder
7122         // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
7123         // client identity accordingly before proceeding.
7124         Identity tlsIdentity = sCallerIdentity.get();
7125         if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7126             Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
7127                     + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
7128             uid = tlsIdentity.uid;
7129             pid = tlsIdentity.pid;
7130         }
7131
7132         return checkComponentPermission(permission, pid, uid, -1, true);
7133     }
7134
7135     /**
7136      * Binder IPC calls go through the public entry point.
7137      * This can be called with or without the global lock held.
7138      */
7139     int checkCallingPermission(String permission) {
7140         return checkPermission(permission,
7141                 Binder.getCallingPid(),
7142                 UserHandle.getAppId(Binder.getCallingUid()));
7143     }
7144
7145     /**
7146      * This can be called with or without the global lock held.
7147      */
7148     void enforceCallingPermission(String permission, String func) {
7149         if (checkCallingPermission(permission)
7150                 == PackageManager.PERMISSION_GRANTED) {
7151             return;
7152         }
7153
7154         String msg = "Permission Denial: " + func + " from pid="
7155                 + Binder.getCallingPid()
7156                 + ", uid=" + Binder.getCallingUid()
7157                 + " requires " + permission;
7158         Slog.w(TAG, msg);
7159         throw new SecurityException(msg);
7160     }
7161
7162     /**
7163      * Determine if UID is holding permissions required to access {@link Uri} in
7164      * the given {@link ProviderInfo}. Final permission checking is always done
7165      * in {@link ContentProvider}.
7166      */
7167     private final boolean checkHoldingPermissionsLocked(
7168             IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
7169         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7170                 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
7171         if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
7172             if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
7173                     != PERMISSION_GRANTED) {
7174                 return false;
7175             }
7176         }
7177         return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
7178     }
7179
7180     private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
7181             GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
7182         if (pi.applicationInfo.uid == uid) {
7183             return true;
7184         } else if (!pi.exported) {
7185             return false;
7186         }
7187
7188         boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
7189         boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
7190         try {
7191             // check if target holds top-level <provider> permissions
7192             if (!readMet && pi.readPermission != null && considerUidPermissions
7193                     && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
7194                 readMet = true;
7195             }
7196             if (!writeMet && pi.writePermission != null && considerUidPermissions
7197                     && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
7198                 writeMet = true;
7199             }
7200
7201             // track if unprotected read/write is allowed; any denied
7202             // <path-permission> below removes this ability
7203             boolean allowDefaultRead = pi.readPermission == null;
7204             boolean allowDefaultWrite = pi.writePermission == null;
7205
7206             // check if target holds any <path-permission> that match uri
7207             final PathPermission[] pps = pi.pathPermissions;
7208             if (pps != null) {
7209                 final String path = grantUri.uri.getPath();
7210                 int i = pps.length;
7211                 while (i > 0 && (!readMet || !writeMet)) {
7212                     i--;
7213                     PathPermission pp = pps[i];
7214                     if (pp.match(path)) {
7215                         if (!readMet) {
7216                             final String pprperm = pp.getReadPermission();
7217                             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7218                                     "Checking read perm for " + pprperm + " for " + pp.getPath()
7219                                     + ": match=" + pp.match(path)
7220                                     + " check=" + pm.checkUidPermission(pprperm, uid));
7221                             if (pprperm != null) {
7222                                 if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7223                                         == PERMISSION_GRANTED) {
7224                                     readMet = true;
7225                                 } else {
7226                                     allowDefaultRead = false;
7227                                 }
7228                             }
7229                         }
7230                         if (!writeMet) {
7231                             final String ppwperm = pp.getWritePermission();
7232                             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7233                                     "Checking write perm " + ppwperm + " for " + pp.getPath()
7234                                     + ": match=" + pp.match(path)
7235                                     + " check=" + pm.checkUidPermission(ppwperm, uid));
7236                             if (ppwperm != null) {
7237                                 if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7238                                         == PERMISSION_GRANTED) {
7239                                     writeMet = true;
7240                                 } else {
7241                                     allowDefaultWrite = false;
7242                                 }
7243                             }
7244                         }
7245                     }
7246                 }
7247             }
7248
7249             // grant unprotected <provider> read/write, if not blocked by
7250             // <path-permission> above
7251             if (allowDefaultRead) readMet = true;
7252             if (allowDefaultWrite) writeMet = true;
7253
7254         } catch (RemoteException e) {
7255             return false;
7256         }
7257
7258         return readMet && writeMet;
7259     }
7260
7261     private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
7262         ProviderInfo pi = null;
7263         ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7264         if (cpr != null) {
7265             pi = cpr.info;
7266         } else {
7267             try {
7268                 pi = AppGlobals.getPackageManager().resolveContentProvider(
7269                         authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
7270             } catch (RemoteException ex) {
7271             }
7272         }
7273         return pi;
7274     }
7275
7276     private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7277         final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7278         if (targetUris != null) {
7279             return targetUris.get(grantUri);
7280         }
7281         return null;
7282     }
7283
7284     private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7285             String targetPkg, int targetUid, GrantUri grantUri) {
7286         ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7287         if (targetUris == null) {
7288             targetUris = Maps.newArrayMap();
7289             mGrantedUriPermissions.put(targetUid, targetUris);
7290         }
7291
7292         UriPermission perm = targetUris.get(grantUri);
7293         if (perm == null) {
7294             perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7295             targetUris.put(grantUri, perm);
7296         }
7297
7298         return perm;
7299     }
7300
7301     private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7302             final int modeFlags) {
7303         final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7304         final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7305                 : UriPermission.STRENGTH_OWNED;
7306
7307         // Root gets to do everything.
7308         if (uid == 0) {
7309             return true;
7310         }
7311
7312         final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7313         if (perms == null) return false;
7314
7315         // First look for exact match
7316         final UriPermission exactPerm = perms.get(grantUri);
7317         if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7318             return true;
7319         }
7320
7321         // No exact match, look for prefixes
7322         final int N = perms.size();
7323         for (int i = 0; i < N; i++) {
7324             final UriPermission perm = perms.valueAt(i);
7325             if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7326                     && perm.getStrength(modeFlags) >= minStrength) {
7327                 return true;
7328             }
7329         }
7330
7331         return false;
7332     }
7333
7334     /**
7335      * @param uri This uri must NOT contain an embedded userId.
7336      * @param userId The userId in which the uri is to be resolved.
7337      */
7338     @Override
7339     public int checkUriPermission(Uri uri, int pid, int uid,
7340             final int modeFlags, int userId, IBinder callerToken) {
7341         enforceNotIsolatedCaller("checkUriPermission");
7342
7343         // Another redirected-binder-call permissions check as in
7344         // {@link checkPermissionWithToken}.
7345         Identity tlsIdentity = sCallerIdentity.get();
7346         if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7347             uid = tlsIdentity.uid;
7348             pid = tlsIdentity.pid;
7349         }
7350
7351         // Our own process gets to do everything.
7352         if (pid == MY_PID) {
7353             return PackageManager.PERMISSION_GRANTED;
7354         }
7355         synchronized (this) {
7356             return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7357                     ? PackageManager.PERMISSION_GRANTED
7358                     : PackageManager.PERMISSION_DENIED;
7359         }
7360     }
7361
7362     /**
7363      * Check if the targetPkg can be granted permission to access uri by
7364      * the callingUid using the given modeFlags.  Throws a security exception
7365      * if callingUid is not allowed to do this.  Returns the uid of the target
7366      * if the URI permission grant should be performed; returns -1 if it is not
7367      * needed (for example targetPkg already has permission to access the URI).
7368      * If you already know the uid of the target, you can supply it in
7369      * lastTargetUid else set that to -1.
7370      */
7371     int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7372             final int modeFlags, int lastTargetUid) {
7373         if (!Intent.isAccessUriMode(modeFlags)) {
7374             return -1;
7375         }
7376
7377         if (targetPkg != null) {
7378             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7379                     "Checking grant " + targetPkg + " permission to " + grantUri);
7380         }
7381
7382         final IPackageManager pm = AppGlobals.getPackageManager();
7383
7384         // If this is not a content: uri, we can't do anything with it.
7385         if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7386             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7387                     "Can't grant URI permission for non-content URI: " + grantUri);
7388             return -1;
7389         }
7390
7391         final String authority = grantUri.uri.getAuthority();
7392         final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7393         if (pi == null) {
7394             Slog.w(TAG, "No content provider found for permission check: " +
7395                     grantUri.uri.toSafeString());
7396             return -1;
7397         }
7398
7399         int targetUid = lastTargetUid;
7400         if (targetUid < 0 && targetPkg != null) {
7401             try {
7402                 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
7403                 if (targetUid < 0) {
7404                     if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7405                             "Can't grant URI permission no uid for: " + targetPkg);
7406                     return -1;
7407                 }
7408             } catch (RemoteException ex) {
7409                 return -1;
7410             }
7411         }
7412
7413         if (targetUid >= 0) {
7414             // First...  does the target actually need this permission?
7415             if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7416                 // No need to grant the target this permission.
7417                 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7418                         "Target " + targetPkg + " already has full permission to " + grantUri);
7419                 return -1;
7420             }
7421         } else {
7422             // First...  there is no target package, so can anyone access it?
7423             boolean allowed = pi.exported;
7424             if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7425                 if (pi.readPermission != null) {
7426                     allowed = false;
7427                 }
7428             }
7429             if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7430                 if (pi.writePermission != null) {
7431                     allowed = false;
7432                 }
7433             }
7434             if (allowed) {
7435                 return -1;
7436             }
7437         }
7438
7439         /* There is a special cross user grant if:
7440          * - The target is on another user.
7441          * - Apps on the current user can access the uri without any uid permissions.
7442          * In this case, we grant a uri permission, even if the ContentProvider does not normally
7443          * grant uri permissions.
7444          */
7445         boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7446                 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7447                 modeFlags, false /*without considering the uid permissions*/);
7448
7449         // Second...  is the provider allowing granting of URI permissions?
7450         if (!specialCrossUserGrant) {
7451             if (!pi.grantUriPermissions) {
7452                 throw new SecurityException("Provider " + pi.packageName
7453                         + "/" + pi.name
7454                         + " does not allow granting of Uri permissions (uri "
7455                         + grantUri + ")");
7456             }
7457             if (pi.uriPermissionPatterns != null) {
7458                 final int N = pi.uriPermissionPatterns.length;
7459                 boolean allowed = false;
7460                 for (int i=0; i<N; i++) {
7461                     if (pi.uriPermissionPatterns[i] != null
7462                             && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7463                         allowed = true;
7464                         break;
7465                     }
7466                 }
7467                 if (!allowed) {
7468                     throw new SecurityException("Provider " + pi.packageName
7469                             + "/" + pi.name
7470                             + " does not allow granting of permission to path of Uri "
7471                             + grantUri);
7472                 }
7473             }
7474         }
7475
7476         // Third...  does the caller itself have permission to access
7477         // this uri?
7478         if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
7479             if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7480                 // Require they hold a strong enough Uri permission
7481                 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7482                     throw new SecurityException("Uid " + callingUid
7483                             + " does not have permission to uri " + grantUri);
7484                 }
7485             }
7486         }
7487         return targetUid;
7488     }
7489
7490     /**
7491      * @param uri This uri must NOT contain an embedded userId.
7492      * @param userId The userId in which the uri is to be resolved.
7493      */
7494     @Override
7495     public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
7496             final int modeFlags, int userId) {
7497         enforceNotIsolatedCaller("checkGrantUriPermission");
7498         synchronized(this) {
7499             return checkGrantUriPermissionLocked(callingUid, targetPkg,
7500                     new GrantUri(userId, uri, false), modeFlags, -1);
7501         }
7502     }
7503
7504     void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
7505             final int modeFlags, UriPermissionOwner owner) {
7506         if (!Intent.isAccessUriMode(modeFlags)) {
7507             return;
7508         }
7509
7510         // So here we are: the caller has the assumed permission
7511         // to the uri, and the target doesn't.  Let's now give this to
7512         // the target.
7513
7514         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7515                 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
7516
7517         final String authority = grantUri.uri.getAuthority();
7518         final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7519         if (pi == null) {
7520             Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
7521             return;
7522         }
7523
7524         if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
7525             grantUri.prefix = true;
7526         }
7527         final UriPermission perm = findOrCreateUriPermissionLocked(
7528                 pi.packageName, targetPkg, targetUid, grantUri);
7529         perm.grantModes(modeFlags, owner);
7530     }
7531
7532     void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7533             final int modeFlags, UriPermissionOwner owner, int targetUserId) {
7534         if (targetPkg == null) {
7535             throw new NullPointerException("targetPkg");
7536         }
7537         int targetUid;
7538         final IPackageManager pm = AppGlobals.getPackageManager();
7539         try {
7540             targetUid = pm.getPackageUid(targetPkg, targetUserId);
7541         } catch (RemoteException ex) {
7542             return;
7543         }
7544
7545         targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
7546                 targetUid);
7547         if (targetUid < 0) {
7548             return;
7549         }
7550
7551         grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
7552                 owner);
7553     }
7554
7555     static class NeededUriGrants extends ArrayList<GrantUri> {
7556         final String targetPkg;
7557         final int targetUid;
7558         final int flags;
7559
7560         NeededUriGrants(String targetPkg, int targetUid, int flags) {
7561             this.targetPkg = targetPkg;
7562             this.targetUid = targetUid;
7563             this.flags = flags;
7564         }
7565     }
7566
7567     /**
7568      * Like checkGrantUriPermissionLocked, but takes an Intent.
7569      */
7570     NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
7571             String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
7572         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7573                 "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
7574                 + " clip=" + (intent != null ? intent.getClipData() : null)
7575                 + " from " + intent + "; flags=0x"
7576                 + Integer.toHexString(intent != null ? intent.getFlags() : 0));
7577
7578         if (targetPkg == null) {
7579             throw new NullPointerException("targetPkg");
7580         }
7581
7582         if (intent == null) {
7583             return null;
7584         }
7585         Uri data = intent.getData();
7586         ClipData clip = intent.getClipData();
7587         if (data == null && clip == null) {
7588             return null;
7589         }
7590         // Default userId for uris in the intent (if they don't specify it themselves)
7591         int contentUserHint = intent.getContentUserHint();
7592         if (contentUserHint == UserHandle.USER_CURRENT) {
7593             contentUserHint = UserHandle.getUserId(callingUid);
7594         }
7595         final IPackageManager pm = AppGlobals.getPackageManager();
7596         int targetUid;
7597         if (needed != null) {
7598             targetUid = needed.targetUid;
7599         } else {
7600             try {
7601                 targetUid = pm.getPackageUid(targetPkg, targetUserId);
7602             } catch (RemoteException ex) {
7603                 return null;
7604             }
7605             if (targetUid < 0) {
7606                 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7607                         "Can't grant URI permission no uid for: " + targetPkg
7608                         + " on user " + targetUserId);
7609                 return null;
7610             }
7611         }
7612         if (data != null) {
7613             GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
7614             targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7615                     targetUid);
7616             if (targetUid > 0) {
7617                 if (needed == null) {
7618                     needed = new NeededUriGrants(targetPkg, targetUid, mode);
7619                 }
7620                 needed.add(grantUri);
7621             }
7622         }
7623         if (clip != null) {
7624             for (int i=0; i<clip.getItemCount(); i++) {
7625                 Uri uri = clip.getItemAt(i).getUri();
7626                 if (uri != null) {
7627                     GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
7628                     targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7629                             targetUid);
7630                     if (targetUid > 0) {
7631                         if (needed == null) {
7632                             needed = new NeededUriGrants(targetPkg, targetUid, mode);
7633                         }
7634                         needed.add(grantUri);
7635                     }
7636                 } else {
7637                     Intent clipIntent = clip.getItemAt(i).getIntent();
7638                     if (clipIntent != null) {
7639                         NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
7640                                 callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
7641                         if (newNeeded != null) {
7642                             needed = newNeeded;
7643                         }
7644                     }
7645                 }
7646             }
7647         }
7648
7649         return needed;
7650     }
7651
7652     /**
7653      * Like grantUriPermissionUncheckedLocked, but takes an Intent.
7654      */
7655     void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
7656             UriPermissionOwner owner) {
7657         if (needed != null) {
7658             for (int i=0; i<needed.size(); i++) {
7659                 GrantUri grantUri = needed.get(i);
7660                 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
7661                         grantUri, needed.flags, owner);
7662             }
7663         }
7664     }
7665
7666     void grantUriPermissionFromIntentLocked(int callingUid,
7667             String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
7668         NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
7669                 intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
7670         if (needed == null) {
7671             return;
7672         }
7673
7674         grantUriPermissionUncheckedFromIntentLocked(needed, owner);
7675     }
7676
7677     /**
7678      * @param uri This uri must NOT contain an embedded userId.
7679      * @param userId The userId in which the uri is to be resolved.
7680      */
7681     @Override
7682     public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
7683             final int modeFlags, int userId) {
7684         enforceNotIsolatedCaller("grantUriPermission");
7685         GrantUri grantUri = new GrantUri(userId, uri, false);
7686         synchronized(this) {
7687             final ProcessRecord r = getRecordForAppLocked(caller);
7688             if (r == null) {
7689                 throw new SecurityException("Unable to find app for caller "
7690                         + caller
7691                         + " when granting permission to uri " + grantUri);
7692             }
7693             if (targetPkg == null) {
7694                 throw new IllegalArgumentException("null target");
7695             }
7696             if (grantUri == null) {
7697                 throw new IllegalArgumentException("null uri");
7698             }
7699
7700             Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
7701                     | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
7702                     | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
7703                     | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
7704
7705             grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
7706                     UserHandle.getUserId(r.uid));
7707         }
7708     }
7709
7710     void removeUriPermissionIfNeededLocked(UriPermission perm) {
7711         if (perm.modeFlags == 0) {
7712             final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7713                     perm.targetUid);
7714             if (perms != null) {
7715                 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7716                         "Removing " + perm.targetUid + " permission to " + perm.uri);
7717
7718                 perms.remove(perm.uri);
7719                 if (perms.isEmpty()) {
7720                     mGrantedUriPermissions.remove(perm.targetUid);
7721                 }
7722             }
7723         }
7724     }
7725
7726     private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
7727         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7728                 "Revoking all granted permissions to " + grantUri);
7729
7730         final IPackageManager pm = AppGlobals.getPackageManager();
7731         final String authority = grantUri.uri.getAuthority();
7732         final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7733         if (pi == null) {
7734             Slog.w(TAG, "No content provider found for permission revoke: "
7735                     + grantUri.toSafeString());
7736             return;
7737         }
7738
7739         // Does the caller have this permission on the URI?
7740         if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7741             // If they don't have direct access to the URI, then revoke any
7742             // ownerless URI permissions that have been granted to them.
7743             final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7744             if (perms != null) {
7745                 boolean persistChanged = false;
7746                 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7747                     final UriPermission perm = it.next();
7748                     if (perm.uri.sourceUserId == grantUri.sourceUserId
7749                             && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7750                         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7751                                 "Revoking non-owned " + perm.targetUid
7752                                 + " permission to " + perm.uri);
7753                         persistChanged |= perm.revokeModes(
7754                                 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
7755                         if (perm.modeFlags == 0) {
7756                             it.remove();
7757                         }
7758                     }
7759                 }
7760                 if (perms.isEmpty()) {
7761                     mGrantedUriPermissions.remove(callingUid);
7762                 }
7763                 if (persistChanged) {
7764                     schedulePersistUriGrants();
7765                 }
7766             }
7767             return;
7768         }
7769
7770         boolean persistChanged = false;
7771
7772         // Go through all of the permissions and remove any that match.
7773         int N = mGrantedUriPermissions.size();
7774         for (int i = 0; i < N; i++) {
7775             final int targetUid = mGrantedUriPermissions.keyAt(i);
7776             final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7777
7778             for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7779                 final UriPermission perm = it.next();
7780                 if (perm.uri.sourceUserId == grantUri.sourceUserId
7781                         && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7782                     if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7783                                 "Revoking " + perm.targetUid + " permission to " + perm.uri);
7784                     persistChanged |= perm.revokeModes(
7785                             modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7786                     if (perm.modeFlags == 0) {
7787                         it.remove();
7788                     }
7789                 }
7790             }
7791
7792             if (perms.isEmpty()) {
7793                 mGrantedUriPermissions.remove(targetUid);
7794                 N--;
7795                 i--;
7796             }
7797         }
7798
7799         if (persistChanged) {
7800             schedulePersistUriGrants();
7801         }
7802     }
7803
7804     /**
7805      * @param uri This uri must NOT contain an embedded userId.
7806      * @param userId The userId in which the uri is to be resolved.
7807      */
7808     @Override
7809     public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
7810             int userId) {
7811         enforceNotIsolatedCaller("revokeUriPermission");
7812         synchronized(this) {
7813             final ProcessRecord r = getRecordForAppLocked(caller);
7814             if (r == null) {
7815                 throw new SecurityException("Unable to find app for caller "
7816                         + caller
7817                         + " when revoking permission to uri " + uri);
7818             }
7819             if (uri == null) {
7820                 Slog.w(TAG, "revokeUriPermission: null uri");
7821                 return;
7822             }
7823
7824             if (!Intent.isAccessUriMode(modeFlags)) {
7825                 return;
7826             }
7827
7828             final String authority = uri.getAuthority();
7829             final ProviderInfo pi = getProviderInfoLocked(authority, userId);
7830             if (pi == null) {
7831                 Slog.w(TAG, "No content provider found for permission revoke: "
7832                         + uri.toSafeString());
7833                 return;
7834             }
7835
7836             revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
7837         }
7838     }
7839
7840     /**
7841      * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
7842      * given package.
7843      *
7844      * @param packageName Package name to match, or {@code null} to apply to all
7845      *            packages.
7846      * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
7847      *            to all users.
7848      * @param persistable If persistable grants should be removed.
7849      */
7850     private void removeUriPermissionsForPackageLocked(
7851             String packageName, int userHandle, boolean persistable) {
7852         if (userHandle == UserHandle.USER_ALL && packageName == null) {
7853             throw new IllegalArgumentException("Must narrow by either package or user");
7854         }
7855
7856         boolean persistChanged = false;
7857
7858         int N = mGrantedUriPermissions.size();
7859         for (int i = 0; i < N; i++) {
7860             final int targetUid = mGrantedUriPermissions.keyAt(i);
7861             final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7862
7863             // Only inspect grants matching user
7864             if (userHandle == UserHandle.USER_ALL
7865                     || userHandle == UserHandle.getUserId(targetUid)) {
7866                 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7867                     final UriPermission perm = it.next();
7868
7869                     // Only inspect grants matching package
7870                     if (packageName == null || perm.sourcePkg.equals(packageName)
7871                             || perm.targetPkg.equals(packageName)) {
7872                         persistChanged |= perm.revokeModes(persistable
7873                                 ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7874
7875                         // Only remove when no modes remain; any persisted grants
7876                         // will keep this alive.
7877                         if (perm.modeFlags == 0) {
7878                             it.remove();
7879                         }
7880                     }
7881                 }
7882
7883                 if (perms.isEmpty()) {
7884                     mGrantedUriPermissions.remove(targetUid);
7885                     N--;
7886                     i--;
7887                 }
7888             }
7889         }
7890
7891         if (persistChanged) {
7892             schedulePersistUriGrants();
7893         }
7894     }
7895
7896     @Override
7897     public IBinder newUriPermissionOwner(String name) {
7898         enforceNotIsolatedCaller("newUriPermissionOwner");
7899         synchronized(this) {
7900             UriPermissionOwner owner = new UriPermissionOwner(this, name);
7901             return owner.getExternalTokenLocked();
7902         }
7903     }
7904
7905     /**
7906      * @param uri This uri must NOT contain an embedded userId.
7907      * @param sourceUserId The userId in which the uri is to be resolved.
7908      * @param targetUserId The userId of the app that receives the grant.
7909      */
7910     @Override
7911     public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
7912             final int modeFlags, int sourceUserId, int targetUserId) {
7913         targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
7914                 targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null);
7915         synchronized(this) {
7916             UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7917             if (owner == null) {
7918                 throw new IllegalArgumentException("Unknown owner: " + token);
7919             }
7920             if (fromUid != Binder.getCallingUid()) {
7921                 if (Binder.getCallingUid() != Process.myUid()) {
7922                     // Only system code can grant URI permissions on behalf
7923                     // of other users.
7924                     throw new SecurityException("nice try");
7925                 }
7926             }
7927             if (targetPkg == null) {
7928                 throw new IllegalArgumentException("null target");
7929             }
7930             if (uri == null) {
7931                 throw new IllegalArgumentException("null uri");
7932             }
7933
7934             grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
7935                     modeFlags, owner, targetUserId);
7936         }
7937     }
7938
7939     /**
7940      * @param uri This uri must NOT contain an embedded userId.
7941      * @param userId The userId in which the uri is to be resolved.
7942      */
7943     @Override
7944     public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
7945         synchronized(this) {
7946             UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7947             if (owner == null) {
7948                 throw new IllegalArgumentException("Unknown owner: " + token);
7949             }
7950
7951             if (uri == null) {
7952                 owner.removeUriPermissionsLocked(mode);
7953             } else {
7954                 owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
7955             }
7956         }
7957     }
7958
7959     private void schedulePersistUriGrants() {
7960         if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
7961             mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
7962                     10 * DateUtils.SECOND_IN_MILLIS);
7963         }
7964     }
7965
7966     private void writeGrantedUriPermissions() {
7967         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
7968
7969         // Snapshot permissions so we can persist without lock
7970         ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
7971         synchronized (this) {
7972             final int size = mGrantedUriPermissions.size();
7973             for (int i = 0; i < size; i++) {
7974                 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7975                 for (UriPermission perm : perms.values()) {
7976                     if (perm.persistedModeFlags != 0) {
7977                         persist.add(perm.snapshot());
7978                     }
7979                 }
7980             }
7981         }
7982
7983         FileOutputStream fos = null;
7984         try {
7985             fos = mGrantFile.startWrite();
7986
7987             XmlSerializer out = new FastXmlSerializer();
7988             out.setOutput(fos, StandardCharsets.UTF_8.name());
7989             out.startDocument(null, true);
7990             out.startTag(null, TAG_URI_GRANTS);
7991             for (UriPermission.Snapshot perm : persist) {
7992                 out.startTag(null, TAG_URI_GRANT);
7993                 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
7994                 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
7995                 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
7996                 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
7997                 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
7998                 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
7999                 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
8000                 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
8001                 out.endTag(null, TAG_URI_GRANT);
8002             }
8003             out.endTag(null, TAG_URI_GRANTS);
8004             out.endDocument();
8005
8006             mGrantFile.finishWrite(fos);
8007         } catch (IOException e) {
8008             if (fos != null) {
8009                 mGrantFile.failWrite(fos);
8010             }
8011         }
8012     }
8013
8014     private void readGrantedUriPermissionsLocked() {
8015         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
8016
8017         final long now = System.currentTimeMillis();
8018
8019         FileInputStream fis = null;
8020         try {
8021             fis = mGrantFile.openRead();
8022             final XmlPullParser in = Xml.newPullParser();
8023             in.setInput(fis, StandardCharsets.UTF_8.name());
8024
8025             int type;
8026             while ((type = in.next()) != END_DOCUMENT) {
8027                 final String tag = in.getName();
8028                 if (type == START_TAG) {
8029                     if (TAG_URI_GRANT.equals(tag)) {
8030                         final int sourceUserId;
8031                         final int targetUserId;
8032                         final int userHandle = readIntAttribute(in,
8033                                 ATTR_USER_HANDLE, UserHandle.USER_NULL);
8034                         if (userHandle != UserHandle.USER_NULL) {
8035                             // For backwards compatibility.
8036                             sourceUserId = userHandle;
8037                             targetUserId = userHandle;
8038                         } else {
8039                             sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
8040                             targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
8041                         }
8042                         final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
8043                         final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
8044                         final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
8045                         final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
8046                         final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
8047                         final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
8048
8049                         // Sanity check that provider still belongs to source package
8050                         final ProviderInfo pi = getProviderInfoLocked(
8051                                 uri.getAuthority(), sourceUserId);
8052                         if (pi != null && sourcePkg.equals(pi.packageName)) {
8053                             int targetUid = -1;
8054                             try {
8055                                 targetUid = AppGlobals.getPackageManager()
8056                                         .getPackageUid(targetPkg, targetUserId);
8057                             } catch (RemoteException e) {
8058                             }
8059                             if (targetUid != -1) {
8060                                 final UriPermission perm = findOrCreateUriPermissionLocked(
8061                                         sourcePkg, targetPkg, targetUid,
8062                                         new GrantUri(sourceUserId, uri, prefix));
8063                                 perm.initPersistedModes(modeFlags, createdTime);
8064                             }
8065                         } else {
8066                             Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
8067                                     + " but instead found " + pi);
8068                         }
8069                     }
8070                 }
8071             }
8072         } catch (FileNotFoundException e) {
8073             // Missing grants is okay
8074         } catch (IOException e) {
8075             Slog.wtf(TAG, "Failed reading Uri grants", e);
8076         } catch (XmlPullParserException e) {
8077             Slog.wtf(TAG, "Failed reading Uri grants", e);
8078         } finally {
8079             IoUtils.closeQuietly(fis);
8080         }
8081     }
8082
8083     /**
8084      * @param uri This uri must NOT contain an embedded userId.
8085      * @param userId The userId in which the uri is to be resolved.
8086      */
8087     @Override
8088     public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8089         enforceNotIsolatedCaller("takePersistableUriPermission");
8090
8091         Preconditions.checkFlagsArgument(modeFlags,
8092                 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8093
8094         synchronized (this) {
8095             final int callingUid = Binder.getCallingUid();
8096             boolean persistChanged = false;
8097             GrantUri grantUri = new GrantUri(userId, uri, false);
8098
8099             UriPermission exactPerm = findUriPermissionLocked(callingUid,
8100                     new GrantUri(userId, uri, false));
8101             UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8102                     new GrantUri(userId, uri, true));
8103
8104             final boolean exactValid = (exactPerm != null)
8105                     && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
8106             final boolean prefixValid = (prefixPerm != null)
8107                     && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
8108
8109             if (!(exactValid || prefixValid)) {
8110                 throw new SecurityException("No persistable permission grants found for UID "
8111                         + callingUid + " and Uri " + grantUri.toSafeString());
8112             }
8113
8114             if (exactValid) {
8115                 persistChanged |= exactPerm.takePersistableModes(modeFlags);
8116             }
8117             if (prefixValid) {
8118                 persistChanged |= prefixPerm.takePersistableModes(modeFlags);
8119             }
8120
8121             persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
8122
8123             if (persistChanged) {
8124                 schedulePersistUriGrants();
8125             }
8126         }
8127     }
8128
8129     /**
8130      * @param uri This uri must NOT contain an embedded userId.
8131      * @param userId The userId in which the uri is to be resolved.
8132      */
8133     @Override
8134     public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8135         enforceNotIsolatedCaller("releasePersistableUriPermission");
8136
8137         Preconditions.checkFlagsArgument(modeFlags,
8138                 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8139
8140         synchronized (this) {
8141             final int callingUid = Binder.getCallingUid();
8142             boolean persistChanged = false;
8143
8144             UriPermission exactPerm = findUriPermissionLocked(callingUid,
8145                     new GrantUri(userId, uri, false));
8146             UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8147                     new GrantUri(userId, uri, true));
8148             if (exactPerm == null && prefixPerm == null) {
8149                 throw new SecurityException("No permission grants found for UID " + callingUid
8150                         + " and Uri " + uri.toSafeString());
8151             }
8152
8153             if (exactPerm != null) {
8154                 persistChanged |= exactPerm.releasePersistableModes(modeFlags);
8155                 removeUriPermissionIfNeededLocked(exactPerm);
8156             }
8157             if (prefixPerm != null) {
8158                 persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
8159                 removeUriPermissionIfNeededLocked(prefixPerm);
8160             }
8161
8162             if (persistChanged) {
8163                 schedulePersistUriGrants();
8164             }
8165         }
8166     }
8167
8168     /**
8169      * Prune any older {@link UriPermission} for the given UID until outstanding
8170      * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
8171      *
8172      * @return if any mutations occured that require persisting.
8173      */
8174     private boolean maybePrunePersistedUriGrantsLocked(int uid) {
8175         final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8176         if (perms == null) return false;
8177         if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
8178
8179         final ArrayList<UriPermission> persisted = Lists.newArrayList();
8180         for (UriPermission perm : perms.values()) {
8181             if (perm.persistedModeFlags != 0) {
8182                 persisted.add(perm);
8183             }
8184         }
8185
8186         final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
8187         if (trimCount <= 0) return false;
8188
8189         Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
8190         for (int i = 0; i < trimCount; i++) {
8191             final UriPermission perm = persisted.get(i);
8192
8193             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8194                     "Trimming grant created at " + perm.persistedCreateTime);
8195
8196             perm.releasePersistableModes(~0);
8197             removeUriPermissionIfNeededLocked(perm);
8198         }
8199
8200         return true;
8201     }
8202
8203     @Override
8204     public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8205             String packageName, boolean incoming) {
8206         enforceNotIsolatedCaller("getPersistedUriPermissions");
8207         Preconditions.checkNotNull(packageName, "packageName");
8208
8209         final int callingUid = Binder.getCallingUid();
8210         final IPackageManager pm = AppGlobals.getPackageManager();
8211         try {
8212             final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
8213             if (packageUid != callingUid) {
8214                 throw new SecurityException(
8215                         "Package " + packageName + " does not belong to calling UID " + callingUid);
8216             }
8217         } catch (RemoteException e) {
8218             throw new SecurityException("Failed to verify package name ownership");
8219         }
8220
8221         final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8222         synchronized (this) {
8223             if (incoming) {
8224                 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8225                         callingUid);
8226                 if (perms == null) {
8227                     Slog.w(TAG, "No permission grants found for " + packageName);
8228                 } else {
8229                     for (UriPermission perm : perms.values()) {
8230                         if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8231                             result.add(perm.buildPersistedPublicApiObject());
8232                         }
8233                     }
8234                 }
8235             } else {
8236                 final int size = mGrantedUriPermissions.size();
8237                 for (int i = 0; i < size; i++) {
8238                     final ArrayMap<GrantUri, UriPermission> perms =
8239                             mGrantedUriPermissions.valueAt(i);
8240                     for (UriPermission perm : perms.values()) {
8241                         if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8242                             result.add(perm.buildPersistedPublicApiObject());
8243                         }
8244                     }
8245                 }
8246             }
8247         }
8248         return new ParceledListSlice<android.content.UriPermission>(result);
8249     }
8250
8251     @Override
8252     public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
8253         synchronized (this) {
8254             ProcessRecord app =
8255                 who != null ? getRecordForAppLocked(who) : null;
8256             if (app == null) return;
8257
8258             Message msg = Message.obtain();
8259             msg.what = WAIT_FOR_DEBUGGER_MSG;
8260             msg.obj = app;
8261             msg.arg1 = waiting ? 1 : 0;
8262             mUiHandler.sendMessage(msg);
8263         }
8264     }
8265
8266     @Override
8267     public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
8268         final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
8269         final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
8270         outInfo.availMem = Process.getFreeMemory();
8271         outInfo.totalMem = Process.getTotalMemory();
8272         outInfo.threshold = homeAppMem;
8273         outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
8274         outInfo.hiddenAppThreshold = cachedAppMem;
8275         outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
8276                 ProcessList.SERVICE_ADJ);
8277         outInfo.visibleAppThreshold = mProcessList.getMemLevel(
8278                 ProcessList.VISIBLE_APP_ADJ);
8279         outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
8280                 ProcessList.FOREGROUND_APP_ADJ);
8281     }
8282
8283     // =========================================================
8284     // TASK MANAGEMENT
8285     // =========================================================
8286
8287     @Override
8288     public List<IAppTask> getAppTasks(String callingPackage) {
8289         int callingUid = Binder.getCallingUid();
8290         long ident = Binder.clearCallingIdentity();
8291
8292         synchronized(this) {
8293             ArrayList<IAppTask> list = new ArrayList<IAppTask>();
8294             try {
8295                 if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
8296
8297                 final int N = mRecentTasks.size();
8298                 for (int i = 0; i < N; i++) {
8299                     TaskRecord tr = mRecentTasks.get(i);
8300                     // Skip tasks that do not match the caller.  We don't need to verify
8301                     // callingPackage, because we are also limiting to callingUid and know
8302                     // that will limit to the correct security sandbox.
8303                     if (tr.effectiveUid != callingUid) {
8304                         continue;
8305                     }
8306                     Intent intent = tr.getBaseIntent();
8307                     if (intent == null ||
8308                             !callingPackage.equals(intent.getComponent().getPackageName())) {
8309                         continue;
8310                     }
8311                     ActivityManager.RecentTaskInfo taskInfo =
8312                             createRecentTaskInfoFromTaskRecord(tr);
8313                     AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8314                     list.add(taskImpl);
8315                 }
8316             } finally {
8317                 Binder.restoreCallingIdentity(ident);
8318             }
8319             return list;
8320         }
8321     }
8322
8323     @Override
8324     public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8325         final int callingUid = Binder.getCallingUid();
8326         ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8327
8328         synchronized(this) {
8329             if (DEBUG_ALL) Slog.v(
8330                 TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8331
8332             final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
8333                     callingUid);
8334
8335             // TODO: Improve with MRU list from all ActivityStacks.
8336             mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8337         }
8338
8339         return list;
8340     }
8341
8342     /**
8343      * Creates a new RecentTaskInfo from a TaskRecord.
8344      */
8345     private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8346         // Update the task description to reflect any changes in the task stack
8347         tr.updateTaskDescription();
8348
8349         // Compose the recent task info
8350         ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8351         rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
8352         rti.persistentId = tr.taskId;
8353         rti.baseIntent = new Intent(tr.getBaseIntent());
8354         rti.origActivity = tr.origActivity;
8355         rti.description = tr.lastDescription;
8356         rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8357         rti.userId = tr.userId;
8358         rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8359         rti.firstActiveTime = tr.firstActiveTime;
8360         rti.lastActiveTime = tr.lastActiveTime;
8361         rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8362         rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8363         rti.numActivities = 0;
8364
8365         ActivityRecord base = null;
8366         ActivityRecord top = null;
8367         ActivityRecord tmp;
8368
8369         for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
8370             tmp = tr.mActivities.get(i);
8371             if (tmp.finishing) {
8372                 continue;
8373             }
8374             base = tmp;
8375             if (top == null || (top.state == ActivityState.INITIALIZING)) {
8376                 top = base;
8377             }
8378             rti.numActivities++;
8379         }
8380
8381         rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
8382         rti.topActivity = (top != null) ? top.intent.getComponent() : null;
8383
8384         return rti;
8385     }
8386
8387     private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
8388         boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
8389                 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
8390         if (!allowed) {
8391             if (checkPermission(android.Manifest.permission.GET_TASKS,
8392                     callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
8393                 // Temporary compatibility: some existing apps on the system image may
8394                 // still be requesting the old permission and not switched to the new
8395                 // one; if so, we'll still allow them full access.  This means we need
8396                 // to see if they are holding the old permission and are a system app.
8397                 try {
8398                     if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
8399                         allowed = true;
8400                         if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
8401                                 + " is using old GET_TASKS but privileged; allowing");
8402                     }
8403                 } catch (RemoteException e) {
8404                 }
8405             }
8406         }
8407         if (!allowed) {
8408             if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
8409                     + " does not hold REAL_GET_TASKS; limiting output");
8410         }
8411         return allowed;
8412     }
8413
8414     @Override
8415     public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8416         final int callingUid = Binder.getCallingUid();
8417         userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8418                 false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8419
8420         final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8421         final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8422         synchronized (this) {
8423             final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
8424                     callingUid);
8425             final boolean detailed = checkCallingPermission(
8426                     android.Manifest.permission.GET_DETAILED_TASKS)
8427                     == PackageManager.PERMISSION_GRANTED;
8428
8429             final int recentsCount = mRecentTasks.size();
8430             ArrayList<ActivityManager.RecentTaskInfo> res =
8431                     new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
8432
8433             final Set<Integer> includedUsers;
8434             if (includeProfiles) {
8435                 includedUsers = getProfileIdsLocked(userId);
8436             } else {
8437                 includedUsers = new HashSet<>();
8438             }
8439             includedUsers.add(Integer.valueOf(userId));
8440
8441             for (int i = 0; i < recentsCount && maxNum > 0; i++) {
8442                 TaskRecord tr = mRecentTasks.get(i);
8443                 // Only add calling user or related users recent tasks
8444                 if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
8445                     if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
8446                     continue;
8447                 }
8448
8449                 // Return the entry if desired by the caller.  We always return
8450                 // the first entry, because callers always expect this to be the
8451                 // foreground app.  We may filter others if the caller has
8452                 // not supplied RECENT_WITH_EXCLUDED and there is some reason
8453                 // we should exclude the entry.
8454
8455                 if (i == 0
8456                         || withExcluded
8457                         || (tr.intent == null)
8458                         || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
8459                                 == 0)) {
8460                     if (!allowed) {
8461                         // If the caller doesn't have the GET_TASKS permission, then only
8462                         // allow them to see a small subset of tasks -- their own and home.
8463                         if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
8464                             if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
8465                             continue;
8466                         }
8467                     }
8468                     if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
8469                         if (tr.stack != null && tr.stack.isHomeStack()) {
8470                             if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8471                                     "Skipping, home stack task: " + tr);
8472                             continue;
8473                         }
8474                     }
8475                     if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
8476                         // Don't include auto remove tasks that are finished or finishing.
8477                         if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8478                                 "Skipping, auto-remove without activity: " + tr);
8479                         continue;
8480                     }
8481                     if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
8482                             && !tr.isAvailable) {
8483                         if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8484                                 "Skipping, unavail real act: " + tr);
8485                         continue;
8486                     }
8487
8488                     ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
8489                     if (!detailed) {
8490                         rti.baseIntent.replaceExtras((Bundle)null);
8491                     }
8492
8493                     res.add(rti);
8494                     maxNum--;
8495                 }
8496             }
8497             return res;
8498         }
8499     }
8500
8501     @Override
8502     public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
8503         synchronized (this) {
8504             enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
8505                     "getTaskThumbnail()");
8506             TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(id, false);
8507             if (tr != null) {
8508                 return tr.getTaskThumbnailLocked();
8509             }
8510         }
8511         return null;
8512     }
8513
8514     @Override
8515     public int addAppTask(IBinder activityToken, Intent intent,
8516             ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
8517         final int callingUid = Binder.getCallingUid();
8518         final long callingIdent = Binder.clearCallingIdentity();
8519
8520         try {
8521             synchronized (this) {
8522                 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8523                 if (r == null) {
8524                     throw new IllegalArgumentException("Activity does not exist; token="
8525                             + activityToken);
8526                 }
8527                 ComponentName comp = intent.getComponent();
8528                 if (comp == null) {
8529                     throw new IllegalArgumentException("Intent " + intent
8530                             + " must specify explicit component");
8531                 }
8532                 if (thumbnail.getWidth() != mThumbnailWidth
8533                         || thumbnail.getHeight() != mThumbnailHeight) {
8534                     throw new IllegalArgumentException("Bad thumbnail size: got "
8535                             + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
8536                             + mThumbnailWidth + "x" + mThumbnailHeight);
8537                 }
8538                 if (intent.getSelector() != null) {
8539                     intent.setSelector(null);
8540                 }
8541                 if (intent.getSourceBounds() != null) {
8542                     intent.setSourceBounds(null);
8543                 }
8544                 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
8545                     if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
8546                         // The caller has added this as an auto-remove task...  that makes no
8547                         // sense, so turn off auto-remove.
8548                         intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
8549                     }
8550                 } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
8551                     // Must be a new task.
8552                     intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8553                 }
8554                 if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
8555                     mLastAddedTaskActivity = null;
8556                 }
8557                 ActivityInfo ainfo = mLastAddedTaskActivity;
8558                 if (ainfo == null) {
8559                     ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
8560                             comp, 0, UserHandle.getUserId(callingUid));
8561                     if (ainfo.applicationInfo.uid != callingUid) {
8562                         throw new SecurityException(
8563                                 "Can't add task for another application: target uid="
8564                                 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
8565                     }
8566                 }
8567
8568                 TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo,
8569                         intent, description);
8570
8571                 int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
8572                 if (trimIdx >= 0) {
8573                     // If this would have caused a trim, then we'll abort because that
8574                     // means it would be added at the end of the list but then just removed.
8575                     return INVALID_TASK_ID;
8576                 }
8577
8578                 final int N = mRecentTasks.size();
8579                 if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
8580                     final TaskRecord tr = mRecentTasks.remove(N - 1);
8581                     tr.removedFromRecents();
8582                 }
8583
8584                 task.inRecents = true;
8585                 mRecentTasks.add(task);
8586                 r.task.stack.addTask(task, false, false);
8587
8588                 task.setLastThumbnail(thumbnail);
8589                 task.freeLastThumbnail();
8590
8591                 return task.taskId;
8592             }
8593         } finally {
8594             Binder.restoreCallingIdentity(callingIdent);
8595         }
8596     }
8597
8598     @Override
8599     public Point getAppTaskThumbnailSize() {
8600         synchronized (this) {
8601             return new Point(mThumbnailWidth,  mThumbnailHeight);
8602         }
8603     }
8604
8605     @Override
8606     public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
8607         synchronized (this) {
8608             ActivityRecord r = ActivityRecord.isInStackLocked(token);
8609             if (r != null) {
8610                 r.setTaskDescription(td);
8611                 r.task.updateTaskDescription();
8612             }
8613         }
8614     }
8615
8616     @Override
8617     public void setTaskResizeable(int taskId, boolean resizeable) {
8618         synchronized (this) {
8619             TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId, false);
8620             if (task == null) {
8621                 Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
8622                 return;
8623             }
8624             if (task.mResizeable != resizeable) {
8625                 task.mResizeable = resizeable;
8626                 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
8627                 mStackSupervisor.resumeTopActivitiesLocked();
8628             }
8629         }
8630     }
8631
8632     @Override
8633     public void resizeTask(int taskId, Rect bounds) {
8634         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8635                 "resizeTask()");
8636         long ident = Binder.clearCallingIdentity();
8637         try {
8638             synchronized (this) {
8639                 TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8640                 if (task == null) {
8641                     Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
8642                     return;
8643                 }
8644                 mStackSupervisor.resizeTaskLocked(task, bounds);
8645             }
8646         } finally {
8647             Binder.restoreCallingIdentity(ident);
8648         }
8649     }
8650
8651     @Override
8652     public Bitmap getTaskDescriptionIcon(String filename) {
8653         if (!FileUtils.isValidExtFilename(filename)
8654                 || !filename.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
8655             throw new IllegalArgumentException("Bad filename: " + filename);
8656         }
8657         return mTaskPersister.getTaskDescriptionIcon(filename);
8658     }
8659
8660     @Override
8661     public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
8662             throws RemoteException {
8663         if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
8664                 opts.getCustomInPlaceResId() == 0) {
8665             throw new IllegalArgumentException("Expected in-place ActivityOption " +
8666                     "with valid animation");
8667         }
8668         mWindowManager.prepareAppTransition(AppTransition.TRANSIT_TASK_IN_PLACE, false);
8669         mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
8670                 opts.getCustomInPlaceResId());
8671         mWindowManager.executeAppTransition();
8672     }
8673
8674     private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess) {
8675         mRecentTasks.remove(tr);
8676         tr.removedFromRecents();
8677         ComponentName component = tr.getBaseIntent().getComponent();
8678         if (component == null) {
8679             Slog.w(TAG, "No component for base intent of task: " + tr);
8680             return;
8681         }
8682
8683         // Find any running services associated with this app and stop if needed.
8684         mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
8685
8686         if (!killProcess) {
8687             return;
8688         }
8689
8690         // Determine if the process(es) for this task should be killed.
8691         final String pkg = component.getPackageName();
8692         ArrayList<ProcessRecord> procsToKill = new ArrayList<>();
8693         ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
8694         for (int i = 0; i < pmap.size(); i++) {
8695
8696             SparseArray<ProcessRecord> uids = pmap.valueAt(i);
8697             for (int j = 0; j < uids.size(); j++) {
8698                 ProcessRecord proc = uids.valueAt(j);
8699                 if (proc.userId != tr.userId) {
8700                     // Don't kill process for a different user.
8701                     continue;
8702                 }
8703                 if (proc == mHomeProcess) {
8704                     // Don't kill the home process along with tasks from the same package.
8705                     continue;
8706                 }
8707                 if (!proc.pkgList.containsKey(pkg)) {
8708                     // Don't kill process that is not associated with this task.
8709                     continue;
8710                 }
8711
8712                 for (int k = 0; k < proc.activities.size(); k++) {
8713                     TaskRecord otherTask = proc.activities.get(k).task;
8714                     if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
8715                         // Don't kill process(es) that has an activity in a different task that is
8716                         // also in recents.
8717                         return;
8718                     }
8719                 }
8720
8721                 if (proc.foregroundServices) {
8722                     // Don't kill process(es) with foreground service.
8723                     return;
8724                 }
8725
8726                 // Add process to kill list.
8727                 procsToKill.add(proc);
8728             }
8729         }
8730
8731         // Kill the running processes.
8732         for (int i = 0; i < procsToKill.size(); i++) {
8733             ProcessRecord pr = procsToKill.get(i);
8734             if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
8735                     && pr.curReceiver == null) {
8736                 pr.kill("remove task", true);
8737             } else {
8738                 // We delay killing processes that are not in the background or running a receiver.
8739                 pr.waitingToKill = "remove task";
8740             }
8741         }
8742     }
8743
8744     private void removeTasksByPackageNameLocked(String packageName, int userId) {
8745         // Remove all tasks with activities in the specified package from the list of recent tasks
8746         for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
8747             TaskRecord tr = mRecentTasks.get(i);
8748             if (tr.userId != userId) continue;
8749
8750             ComponentName cn = tr.intent.getComponent();
8751             if (cn != null && cn.getPackageName().equals(packageName)) {
8752                 // If the package name matches, remove the task.
8753                 removeTaskByIdLocked(tr.taskId, true);
8754             }
8755         }
8756     }
8757
8758     private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
8759             int userId) {
8760
8761         for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
8762             TaskRecord tr = mRecentTasks.get(i);
8763             if (userId != UserHandle.USER_ALL && tr.userId != userId) {
8764                 continue;
8765             }
8766
8767             ComponentName cn = tr.intent.getComponent();
8768             final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
8769                     && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
8770             if (sameComponent) {
8771                 removeTaskByIdLocked(tr.taskId, false);
8772             }
8773         }
8774     }
8775
8776     /**
8777      * Removes the task with the specified task id.
8778      *
8779      * @param taskId Identifier of the task to be removed.
8780      * @param killProcess Kill any process associated with the task if possible.
8781      * @return Returns true if the given task was found and removed.
8782      */
8783     private boolean removeTaskByIdLocked(int taskId, boolean killProcess) {
8784         TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(taskId, false);
8785         if (tr != null) {
8786             tr.removeTaskActivitiesLocked();
8787             cleanUpRemovedTaskLocked(tr, killProcess);
8788             if (tr.isPersistable) {
8789                 notifyTaskPersisterLocked(null, true);
8790             }
8791             return true;
8792         }
8793         Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
8794         return false;
8795     }
8796
8797     @Override
8798     public boolean removeTask(int taskId) {
8799         synchronized (this) {
8800             enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
8801                     "removeTask()");
8802             long ident = Binder.clearCallingIdentity();
8803             try {
8804                 return removeTaskByIdLocked(taskId, true);
8805             } finally {
8806                 Binder.restoreCallingIdentity(ident);
8807             }
8808         }
8809     }
8810
8811     /**
8812      * TODO: Add mController hook
8813      */
8814     @Override
8815     public void moveTaskToFront(int taskId, int flags, Bundle options) {
8816         enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
8817
8818         if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
8819         synchronized(this) {
8820             moveTaskToFrontLocked(taskId, flags, options);
8821         }
8822     }
8823
8824     void moveTaskToFrontLocked(int taskId, int flags, Bundle options) {
8825         if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8826                 Binder.getCallingUid(), -1, -1, "Task to front")) {
8827             ActivityOptions.abort(options);
8828             return;
8829         }
8830         final long origId = Binder.clearCallingIdentity();
8831         try {
8832             final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8833             if (task == null) {
8834                 Slog.d(TAG, "Could not find task for id: "+ taskId);
8835                 return;
8836             }
8837             if (mStackSupervisor.isLockTaskModeViolation(task)) {
8838                 mStackSupervisor.showLockTaskToast();
8839                 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
8840                 return;
8841             }
8842             final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
8843             if (prev != null && prev.isRecentsActivity()) {
8844                 task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
8845             }
8846             mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront");
8847         } finally {
8848             Binder.restoreCallingIdentity(origId);
8849         }
8850         ActivityOptions.abort(options);
8851     }
8852
8853     /**
8854      * Moves an activity, and all of the other activities within the same task, to the bottom
8855      * of the history stack.  The activity's order within the task is unchanged.
8856      *
8857      * @param token A reference to the activity we wish to move
8858      * @param nonRoot If false then this only works if the activity is the root
8859      *                of a task; if true it will work for any activity in a task.
8860      * @return Returns true if the move completed, false if not.
8861      */
8862     @Override
8863     public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
8864         enforceNotIsolatedCaller("moveActivityTaskToBack");
8865         synchronized(this) {
8866             final long origId = Binder.clearCallingIdentity();
8867             try {
8868                 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
8869                 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8870                 if (task != null) {
8871                     if (mStackSupervisor.isLockedTask(task)) {
8872                         mStackSupervisor.showLockTaskToast();
8873                         return false;
8874                     }
8875                     return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
8876                 }
8877             } finally {
8878                 Binder.restoreCallingIdentity(origId);
8879             }
8880         }
8881         return false;
8882     }
8883
8884     @Override
8885     public void moveTaskBackwards(int task) {
8886         enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8887                 "moveTaskBackwards()");
8888
8889         synchronized(this) {
8890             if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8891                     Binder.getCallingUid(), -1, -1, "Task backwards")) {
8892                 return;
8893             }
8894             final long origId = Binder.clearCallingIdentity();
8895             moveTaskBackwardsLocked(task);
8896             Binder.restoreCallingIdentity(origId);
8897         }
8898     }
8899
8900     private final void moveTaskBackwardsLocked(int task) {
8901         Slog.e(TAG, "moveTaskBackwards not yet implemented!");
8902     }
8903
8904     @Override
8905     public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
8906             IActivityContainerCallback callback) throws RemoteException {
8907         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8908                 "createActivityContainer()");
8909         synchronized (this) {
8910             if (parentActivityToken == null) {
8911                 throw new IllegalArgumentException("parent token must not be null");
8912             }
8913             ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
8914             if (r == null) {
8915                 return null;
8916             }
8917             if (callback == null) {
8918                 throw new IllegalArgumentException("callback must not be null");
8919             }
8920             return mStackSupervisor.createVirtualActivityContainer(r, callback);
8921         }
8922     }
8923
8924     @Override
8925     public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
8926         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8927                 "deleteActivityContainer()");
8928         synchronized (this) {
8929             mStackSupervisor.deleteActivityContainer(container);
8930         }
8931     }
8932
8933     @Override
8934     public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
8935         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8936                 "createStackOnDisplay()");
8937         synchronized (this) {
8938             final int stackId = mStackSupervisor.getNextStackId();
8939             final ActivityStack stack = mStackSupervisor.createStackOnDisplay(stackId, displayId);
8940             if (stack == null) {
8941                 return null;
8942             }
8943             return stack.mActivityContainer;
8944         }
8945     }
8946
8947     @Override
8948     public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
8949         synchronized (this) {
8950             ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
8951             if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
8952                 return stack.mActivityContainer.getDisplayId();
8953             }
8954             return Display.DEFAULT_DISPLAY;
8955         }
8956     }
8957
8958     @Override
8959     public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
8960         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8961                 "moveTaskToStack()");
8962         if (stackId == HOME_STACK_ID) {
8963             Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
8964                     new RuntimeException("here").fillInStackTrace());
8965         }
8966         synchronized (this) {
8967             long ident = Binder.clearCallingIdentity();
8968             try {
8969                 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
8970                         + " to stackId=" + stackId + " toTop=" + toTop);
8971                 mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop);
8972             } finally {
8973                 Binder.restoreCallingIdentity(ident);
8974             }
8975         }
8976     }
8977
8978     @Override
8979     public void resizeStack(int stackId, Rect bounds) {
8980         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8981                 "resizeStack()");
8982         long ident = Binder.clearCallingIdentity();
8983         try {
8984             synchronized (this) {
8985                 mStackSupervisor.resizeStackLocked(stackId, bounds);
8986             }
8987         } finally {
8988             Binder.restoreCallingIdentity(ident);
8989         }
8990     }
8991
8992     @Override
8993     public List<StackInfo> getAllStackInfos() {
8994         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8995                 "getAllStackInfos()");
8996         long ident = Binder.clearCallingIdentity();
8997         try {
8998             synchronized (this) {
8999                 return mStackSupervisor.getAllStackInfosLocked();
9000             }
9001         } finally {
9002             Binder.restoreCallingIdentity(ident);
9003         }
9004     }
9005
9006     @Override
9007     public StackInfo getStackInfo(int stackId) {
9008         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9009                 "getStackInfo()");
9010         long ident = Binder.clearCallingIdentity();
9011         try {
9012             synchronized (this) {
9013                 return mStackSupervisor.getStackInfoLocked(stackId);
9014             }
9015         } finally {
9016             Binder.restoreCallingIdentity(ident);
9017         }
9018     }
9019
9020     @Override
9021     public boolean isInHomeStack(int taskId) {
9022         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9023                 "getStackInfo()");
9024         long ident = Binder.clearCallingIdentity();
9025         try {
9026             synchronized (this) {
9027                 TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(taskId, false);
9028                 return tr != null && tr.stack != null && tr.stack.isHomeStack();
9029             }
9030         } finally {
9031             Binder.restoreCallingIdentity(ident);
9032         }
9033     }
9034
9035     @Override
9036     public int getTaskForActivity(IBinder token, boolean onlyRoot) {
9037         synchronized(this) {
9038             return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
9039         }
9040     }
9041
9042     @Override
9043     public void updateDeviceOwner(String packageName) {
9044         final int callingUid = Binder.getCallingUid();
9045         if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
9046             throw new SecurityException("updateDeviceOwner called from non-system process");
9047         }
9048         synchronized (this) {
9049             mDeviceOwnerName = packageName;
9050         }
9051     }
9052
9053     @Override
9054     public void updateLockTaskPackages(int userId, String[] packages) {
9055         final int callingUid = Binder.getCallingUid();
9056         if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
9057             throw new SecurityException("updateLockTaskPackage called from non-system process");
9058         }
9059         synchronized (this) {
9060             if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
9061                     Arrays.toString(packages));
9062             mLockTaskPackages.put(userId, packages);
9063             mStackSupervisor.onLockTaskPackagesUpdatedLocked();
9064         }
9065     }
9066
9067
9068     void startLockTaskModeLocked(TaskRecord task) {
9069         if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
9070         if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
9071             return;
9072         }
9073
9074         // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
9075         // is initiated by system after the pinning request was shown and locked mode is initiated
9076         // by an authorized app directly
9077         final int callingUid = Binder.getCallingUid();
9078         boolean isSystemInitiated = callingUid == Process.SYSTEM_UID;
9079         long ident = Binder.clearCallingIdentity();
9080         try {
9081             final ActivityStack stack = mStackSupervisor.getFocusedStack();
9082             if (!isSystemInitiated) {
9083                 task.mLockTaskUid = callingUid;
9084                 if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
9085                     // startLockTask() called by app and task mode is lockTaskModeDefault.
9086                     if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
9087                     StatusBarManagerInternal statusBarManager =
9088                             LocalServices.getService(StatusBarManagerInternal.class);
9089                     if (statusBarManager != null) {
9090                         statusBarManager.showScreenPinningRequest();
9091                     }
9092                     return;
9093                 }
9094
9095                 if (stack == null || task != stack.topTask()) {
9096                     throw new IllegalArgumentException("Invalid task, not in foreground");
9097                 }
9098             }
9099             if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
9100                     "Locking fully");
9101             mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
9102                     ActivityManager.LOCK_TASK_MODE_PINNED :
9103                     ActivityManager.LOCK_TASK_MODE_LOCKED,
9104                     "startLockTask", true);
9105         } finally {
9106             Binder.restoreCallingIdentity(ident);
9107         }
9108     }
9109
9110     @Override
9111     public void startLockTaskMode(int taskId) {
9112         synchronized (this) {
9113             final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9114             if (task != null) {
9115                 startLockTaskModeLocked(task);
9116             }
9117         }
9118     }
9119
9120     @Override
9121     public void startLockTaskMode(IBinder token) {
9122         synchronized (this) {
9123             final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9124             if (r == null) {
9125                 return;
9126             }
9127             final TaskRecord task = r.task;
9128             if (task != null) {
9129                 startLockTaskModeLocked(task);
9130             }
9131         }
9132     }
9133
9134     @Override
9135     public void startLockTaskModeOnCurrent() throws RemoteException {
9136         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9137                 "startLockTaskModeOnCurrent");
9138         long ident = Binder.clearCallingIdentity();
9139         try {
9140             synchronized (this) {
9141                 ActivityRecord r = mStackSupervisor.topRunningActivityLocked();
9142                 if (r != null) {
9143                     startLockTaskModeLocked(r.task);
9144                 }
9145             }
9146         } finally {
9147             Binder.restoreCallingIdentity(ident);
9148         }
9149     }
9150
9151     @Override
9152     public void stopLockTaskMode() {
9153         final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
9154         if (lockTask == null) {
9155             // Our work here is done.
9156             return;
9157         }
9158
9159         final int callingUid = Binder.getCallingUid();
9160         final int lockTaskUid = lockTask.mLockTaskUid;
9161         // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
9162         // It is possible lockTaskMode was started by the system process because
9163         // android:lockTaskMode is set to a locking value in the application manifest instead of
9164         // the app calling startLockTaskMode. In this case {@link TaskRecord.mLockTaskUid} will
9165         // be 0, so we compare the callingUid to the {@link TaskRecord.effectiveUid} instead.
9166         if (getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_LOCKED &&
9167                 callingUid != lockTaskUid
9168                 && (lockTaskUid != 0
9169                     || (lockTaskUid == 0 && callingUid != lockTask.effectiveUid))) {
9170             throw new SecurityException("Invalid uid, expected " + lockTaskUid
9171                     + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
9172         }
9173
9174         long ident = Binder.clearCallingIdentity();
9175         try {
9176             Log.d(TAG, "stopLockTaskMode");
9177             // Stop lock task
9178             synchronized (this) {
9179                 mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
9180                         "stopLockTask", true);
9181             }
9182         } finally {
9183             Binder.restoreCallingIdentity(ident);
9184         }
9185     }
9186
9187     @Override
9188     public void stopLockTaskModeOnCurrent() throws RemoteException {
9189         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9190                 "stopLockTaskModeOnCurrent");
9191         long ident = Binder.clearCallingIdentity();
9192         try {
9193             stopLockTaskMode();
9194         } finally {
9195             Binder.restoreCallingIdentity(ident);
9196         }
9197     }
9198
9199     @Override
9200     public boolean isInLockTaskMode() {
9201         return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
9202     }
9203
9204     @Override
9205     public int getLockTaskModeState() {
9206         synchronized (this) {
9207             return mStackSupervisor.getLockTaskModeState();
9208         }
9209     }
9210
9211     @Override
9212     public void showLockTaskEscapeMessage(IBinder token) {
9213         synchronized (this) {
9214             final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9215             if (r == null) {
9216                 return;
9217             }
9218             mStackSupervisor.showLockTaskEscapeMessageLocked(r.task);
9219         }
9220     }
9221
9222     // =========================================================
9223     // CONTENT PROVIDERS
9224     // =========================================================
9225
9226     private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
9227         List<ProviderInfo> providers = null;
9228         try {
9229             ParceledListSlice<ProviderInfo> slice = AppGlobals.getPackageManager().
9230                 queryContentProviders(app.processName, app.uid,
9231                         STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
9232             providers = slice != null ? slice.getList() : null;
9233         } catch (RemoteException ex) {
9234         }
9235         if (DEBUG_MU) Slog.v(TAG_MU,
9236                 "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
9237         int userId = app.userId;
9238         if (providers != null) {
9239             int N = providers.size();
9240             app.pubProviders.ensureCapacity(N + app.pubProviders.size());
9241             for (int i=0; i<N; i++) {
9242                 ProviderInfo cpi =
9243                     (ProviderInfo)providers.get(i);
9244                 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9245                         cpi.name, cpi.flags);
9246                 if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_OWNER) {
9247                     // This is a singleton provider, but a user besides the
9248                     // default user is asking to initialize a process it runs
9249                     // in...  well, no, it doesn't actually run in this process,
9250                     // it runs in the process of the default user.  Get rid of it.
9251                     providers.remove(i);
9252                     N--;
9253                     i--;
9254                     continue;
9255                 }
9256
9257                 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9258                 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
9259                 if (cpr == null) {
9260                     cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
9261                     mProviderMap.putProviderByClass(comp, cpr);
9262                 }
9263                 if (DEBUG_MU) Slog.v(TAG_MU,
9264                         "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
9265                 app.pubProviders.put(cpi.name, cpr);
9266                 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
9267                     // Don't add this if it is a platform component that is marked
9268                     // to run in multiple processes, because this is actually
9269                     // part of the framework so doesn't make sense to track as a
9270                     // separate apk in the process.
9271                     app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
9272                             mProcessStats);
9273                 }
9274                 ensurePackageDexOpt(cpi.applicationInfo.packageName);
9275             }
9276         }
9277         return providers;
9278     }
9279
9280     /**
9281      * Check if {@link ProcessRecord} has a possible chance at accessing the
9282      * given {@link ProviderInfo}. Final permission checking is always done
9283      * in {@link ContentProvider}.
9284      */
9285     private final String checkContentProviderPermissionLocked(
9286             ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
9287         final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
9288         final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
9289         boolean checkedGrants = false;
9290         if (checkUser) {
9291             // Looking for cross-user grants before enforcing the typical cross-users permissions
9292             int tmpTargetUserId = unsafeConvertIncomingUser(userId);
9293             if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
9294                 if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
9295                     return null;
9296                 }
9297                 checkedGrants = true;
9298             }
9299             userId = handleIncomingUser(callingPid, callingUid, userId,
9300                     false, ALLOW_NON_FULL,
9301                     "checkContentProviderPermissionLocked " + cpi.authority, null);
9302             if (userId != tmpTargetUserId) {
9303                 // When we actually went to determine the final targer user ID, this ended
9304                 // up different than our initial check for the authority.  This is because
9305                 // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
9306                 // SELF.  So we need to re-check the grants again.
9307                 checkedGrants = false;
9308             }
9309         }
9310         if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
9311                 cpi.applicationInfo.uid, cpi.exported)
9312                 == PackageManager.PERMISSION_GRANTED) {
9313             return null;
9314         }
9315         if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
9316                 cpi.applicationInfo.uid, cpi.exported)
9317                 == PackageManager.PERMISSION_GRANTED) {
9318             return null;
9319         }
9320
9321         PathPermission[] pps = cpi.pathPermissions;
9322         if (pps != null) {
9323             int i = pps.length;
9324             while (i > 0) {
9325                 i--;
9326                 PathPermission pp = pps[i];
9327                 String pprperm = pp.getReadPermission();
9328                 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
9329                         cpi.applicationInfo.uid, cpi.exported)
9330                         == PackageManager.PERMISSION_GRANTED) {
9331                     return null;
9332                 }
9333                 String ppwperm = pp.getWritePermission();
9334                 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
9335                         cpi.applicationInfo.uid, cpi.exported)
9336                         == PackageManager.PERMISSION_GRANTED) {
9337                     return null;
9338                 }
9339             }
9340         }
9341         if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
9342             return null;
9343         }
9344
9345         String msg;
9346         if (!cpi.exported) {
9347             msg = "Permission Denial: opening provider " + cpi.name
9348                     + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9349                     + ", uid=" + callingUid + ") that is not exported from uid "
9350                     + cpi.applicationInfo.uid;
9351         } else {
9352             msg = "Permission Denial: opening provider " + cpi.name
9353                     + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9354                     + ", uid=" + callingUid + ") requires "
9355                     + cpi.readPermission + " or " + cpi.writePermission;
9356         }
9357         Slog.w(TAG, msg);
9358         return msg;
9359     }
9360
9361     /**
9362      * Returns if the ContentProvider has granted a uri to callingUid
9363      */
9364     boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
9365         final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
9366         if (perms != null) {
9367             for (int i=perms.size()-1; i>=0; i--) {
9368                 GrantUri grantUri = perms.keyAt(i);
9369                 if (grantUri.sourceUserId == userId || !checkUser) {
9370                     if (matchesProvider(grantUri.uri, cpi)) {
9371                         return true;
9372                     }
9373                 }
9374             }
9375         }
9376         return false;
9377     }
9378
9379     /**
9380      * Returns true if the uri authority is one of the authorities specified in the provider.
9381      */
9382     boolean matchesProvider(Uri uri, ProviderInfo cpi) {
9383         String uriAuth = uri.getAuthority();
9384         String cpiAuth = cpi.authority;
9385         if (cpiAuth.indexOf(';') == -1) {
9386             return cpiAuth.equals(uriAuth);
9387         }
9388         String[] cpiAuths = cpiAuth.split(";");
9389         int length = cpiAuths.length;
9390         for (int i = 0; i < length; i++) {
9391             if (cpiAuths[i].equals(uriAuth)) return true;
9392         }
9393         return false;
9394     }
9395
9396     ContentProviderConnection incProviderCountLocked(ProcessRecord r,
9397             final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9398         if (r != null) {
9399             for (int i=0; i<r.conProviders.size(); i++) {
9400                 ContentProviderConnection conn = r.conProviders.get(i);
9401                 if (conn.provider == cpr) {
9402                     if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
9403                             "Adding provider requested by "
9404                             + r.processName + " from process "
9405                             + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9406                             + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9407                     if (stable) {
9408                         conn.stableCount++;
9409                         conn.numStableIncs++;
9410                     } else {
9411                         conn.unstableCount++;
9412                         conn.numUnstableIncs++;
9413                     }
9414                     return conn;
9415                 }
9416             }
9417             ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
9418             if (stable) {
9419                 conn.stableCount = 1;
9420                 conn.numStableIncs = 1;
9421             } else {
9422                 conn.unstableCount = 1;
9423                 conn.numUnstableIncs = 1;
9424             }
9425             cpr.connections.add(conn);
9426             r.conProviders.add(conn);
9427             startAssociationLocked(r.uid, r.processName, cpr.uid, cpr.name, cpr.info.processName);
9428             return conn;
9429         }
9430         cpr.addExternalProcessHandleLocked(externalProcessToken);
9431         return null;
9432     }
9433
9434     boolean decProviderCountLocked(ContentProviderConnection conn,
9435             ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9436         if (conn != null) {
9437             cpr = conn.provider;
9438             if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
9439                     "Removing provider requested by "
9440                     + conn.client.processName + " from process "
9441                     + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9442                     + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9443             if (stable) {
9444                 conn.stableCount--;
9445             } else {
9446                 conn.unstableCount--;
9447             }
9448             if (conn.stableCount == 0 && conn.unstableCount == 0) {
9449                 cpr.connections.remove(conn);
9450                 conn.client.conProviders.remove(conn);
9451                 stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
9452                 return true;
9453             }
9454             return false;
9455         }
9456         cpr.removeExternalProcessHandleLocked(externalProcessToken);
9457         return false;
9458     }
9459
9460     private void checkTime(long startTime, String where) {
9461         long now = SystemClock.elapsedRealtime();
9462         if ((now-startTime) > 1000) {
9463             // If we are taking more than a second, log about it.
9464             Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
9465         }
9466     }
9467
9468     private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
9469             String name, IBinder token, boolean stable, int userId) {
9470         ContentProviderRecord cpr;
9471         ContentProviderConnection conn = null;
9472         ProviderInfo cpi = null;
9473
9474         synchronized(this) {
9475             long startTime = SystemClock.elapsedRealtime();
9476
9477             ProcessRecord r = null;
9478             if (caller != null) {
9479                 r = getRecordForAppLocked(caller);
9480                 if (r == null) {
9481                     throw new SecurityException(
9482                             "Unable to find app for caller " + caller
9483                           + " (pid=" + Binder.getCallingPid()
9484                           + ") when getting content provider " + name);
9485                 }
9486             }
9487
9488             boolean checkCrossUser = true;
9489
9490             checkTime(startTime, "getContentProviderImpl: getProviderByName");
9491
9492             // First check if this content provider has been published...
9493             cpr = mProviderMap.getProviderByName(name, userId);
9494             // If that didn't work, check if it exists for user 0 and then
9495             // verify that it's a singleton provider before using it.
9496             if (cpr == null && userId != UserHandle.USER_OWNER) {
9497                 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
9498                 if (cpr != null) {
9499                     cpi = cpr.info;
9500                     if (isSingleton(cpi.processName, cpi.applicationInfo,
9501                             cpi.name, cpi.flags)
9502                             && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
9503                         userId = UserHandle.USER_OWNER;
9504                         checkCrossUser = false;
9505                     } else {
9506                         cpr = null;
9507                         cpi = null;
9508                     }
9509                 }
9510             }
9511
9512             boolean providerRunning = cpr != null;
9513             if (providerRunning) {
9514                 cpi = cpr.info;
9515                 String msg;
9516                 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9517                 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
9518                         != null) {
9519                     throw new SecurityException(msg);
9520                 }
9521                 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9522
9523                 if (r != null && cpr.canRunHere(r)) {
9524                     // This provider has been published or is in the process
9525                     // of being published...  but it is also allowed to run
9526                     // in the caller's process, so don't make a connection
9527                     // and just let the caller instantiate its own instance.
9528                     ContentProviderHolder holder = cpr.newHolder(null);
9529                     // don't give caller the provider object, it needs
9530                     // to make its own.
9531                     holder.provider = null;
9532                     return holder;
9533                 }
9534
9535                 final long origId = Binder.clearCallingIdentity();
9536
9537                 checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
9538
9539                 // In this case the provider instance already exists, so we can
9540                 // return it right away.
9541                 conn = incProviderCountLocked(r, cpr, token, stable);
9542                 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
9543                     if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
9544                         // If this is a perceptible app accessing the provider,
9545                         // make sure to count it as being accessed and thus
9546                         // back up on the LRU list.  This is good because
9547                         // content providers are often expensive to start.
9548                         checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
9549                         updateLruProcessLocked(cpr.proc, false, null);
9550                         checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
9551                     }
9552                 }
9553
9554                 if (cpr.proc != null) {
9555                     if (false) {
9556                         if (cpr.name.flattenToShortString().equals(
9557                                 "com.android.providers.calendar/.CalendarProvider2")) {
9558                             Slog.v(TAG, "****************** KILLING "
9559                                 + cpr.name.flattenToShortString());
9560                             Process.killProcess(cpr.proc.pid);
9561                         }
9562                     }
9563                     checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
9564                     boolean success = updateOomAdjLocked(cpr.proc);
9565                     maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
9566                     checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
9567                     if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
9568                     // NOTE: there is still a race here where a signal could be
9569                     // pending on the process even though we managed to update its
9570                     // adj level.  Not sure what to do about this, but at least
9571                     // the race is now smaller.
9572                     if (!success) {
9573                         // Uh oh...  it looks like the provider's process
9574                         // has been killed on us.  We need to wait for a new
9575                         // process to be started, and make sure its death
9576                         // doesn't kill our process.
9577                         Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
9578                                 + " is crashing; detaching " + r);
9579                         boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
9580                         checkTime(startTime, "getContentProviderImpl: before appDied");
9581                         appDiedLocked(cpr.proc);
9582                         checkTime(startTime, "getContentProviderImpl: after appDied");
9583                         if (!lastRef) {
9584                             // This wasn't the last ref our process had on
9585                             // the provider...  we have now been killed, bail.
9586                             return null;
9587                         }
9588                         providerRunning = false;
9589                         conn = null;
9590                     }
9591                 }
9592
9593                 Binder.restoreCallingIdentity(origId);
9594             }
9595
9596             boolean singleton;
9597             if (!providerRunning) {
9598                 try {
9599                     checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
9600                     cpi = AppGlobals.getPackageManager().
9601                         resolveContentProvider(name,
9602                             STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
9603                     checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
9604                 } catch (RemoteException ex) {
9605                 }
9606                 if (cpi == null) {
9607                     return null;
9608                 }
9609                 // If the provider is a singleton AND
9610                 // (it's a call within the same user || the provider is a
9611                 // privileged app)
9612                 // Then allow connecting to the singleton provider
9613                 singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9614                         cpi.name, cpi.flags)
9615                         && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
9616                 if (singleton) {
9617                     userId = UserHandle.USER_OWNER;
9618                 }
9619                 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
9620                 checkTime(startTime, "getContentProviderImpl: got app info for user");
9621
9622                 String msg;
9623                 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9624                 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
9625                         != null) {
9626                     throw new SecurityException(msg);
9627                 }
9628                 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9629
9630                 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
9631                         && !cpi.processName.equals("system")) {
9632                     // If this content provider does not run in the system
9633                     // process, and the system is not yet ready to run other
9634                     // processes, then fail fast instead of hanging.
9635                     throw new IllegalArgumentException(
9636                             "Attempt to launch content provider before system ready");
9637                 }
9638
9639                 // Make sure that the user who owns this provider is running.  If not,
9640                 // we don't want to allow it to run.
9641                 if (!isUserRunningLocked(userId, false)) {
9642                     Slog.w(TAG, "Unable to launch app "
9643                             + cpi.applicationInfo.packageName + "/"
9644                             + cpi.applicationInfo.uid + " for provider "
9645                             + name + ": user " + userId + " is stopped");
9646                     return null;
9647                 }
9648
9649                 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9650                 checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
9651                 cpr = mProviderMap.getProviderByClass(comp, userId);
9652                 checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
9653                 final boolean firstClass = cpr == null;
9654                 if (firstClass) {
9655                     final long ident = Binder.clearCallingIdentity();
9656                     try {
9657                         checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
9658                         ApplicationInfo ai =
9659                             AppGlobals.getPackageManager().
9660                                 getApplicationInfo(
9661                                         cpi.applicationInfo.packageName,
9662                                         STOCK_PM_FLAGS, userId);
9663                         checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
9664                         if (ai == null) {
9665                             Slog.w(TAG, "No package info for content provider "
9666                                     + cpi.name);
9667                             return null;
9668                         }
9669                         ai = getAppInfoForUser(ai, userId);
9670                         cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
9671                     } catch (RemoteException ex) {
9672                         // pm is in same process, this will never happen.
9673                     } finally {
9674                         Binder.restoreCallingIdentity(ident);
9675                     }
9676                 }
9677
9678                 checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
9679
9680                 if (r != null && cpr.canRunHere(r)) {
9681                     // If this is a multiprocess provider, then just return its
9682                     // info and allow the caller to instantiate it.  Only do
9683                     // this if the provider is the same user as the caller's
9684                     // process, or can run as root (so can be in any process).
9685                     return cpr.newHolder(null);
9686                 }
9687
9688                 if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
9689                             + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
9690                             + cpr.info.name + " callers=" + Debug.getCallers(6));
9691
9692                 // This is single process, and our app is now connecting to it.
9693                 // See if we are already in the process of launching this
9694                 // provider.
9695                 final int N = mLaunchingProviders.size();
9696                 int i;
9697                 for (i = 0; i < N; i++) {
9698                     if (mLaunchingProviders.get(i) == cpr) {
9699                         break;
9700                     }
9701                 }
9702
9703                 // If the provider is not already being launched, then get it
9704                 // started.
9705                 if (i >= N) {
9706                     final long origId = Binder.clearCallingIdentity();
9707
9708                     try {
9709                         // Content provider is now in use, its package can't be stopped.
9710                         try {
9711                             checkTime(startTime, "getContentProviderImpl: before set stopped state");
9712                             AppGlobals.getPackageManager().setPackageStoppedState(
9713                                     cpr.appInfo.packageName, false, userId);
9714                             checkTime(startTime, "getContentProviderImpl: after set stopped state");
9715                         } catch (RemoteException e) {
9716                         } catch (IllegalArgumentException e) {
9717                             Slog.w(TAG, "Failed trying to unstop package "
9718                                     + cpr.appInfo.packageName + ": " + e);
9719                         }
9720
9721                         // Use existing process if already started
9722                         checkTime(startTime, "getContentProviderImpl: looking for process record");
9723                         ProcessRecord proc = getProcessRecordLocked(
9724                                 cpi.processName, cpr.appInfo.uid, false);
9725                         if (proc != null && proc.thread != null) {
9726                             if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
9727                                     "Installing in existing process " + proc);
9728                             if (!proc.pubProviders.containsKey(cpi.name)) {
9729                                 checkTime(startTime, "getContentProviderImpl: scheduling install");
9730                                 proc.pubProviders.put(cpi.name, cpr);
9731                                 try {
9732                                     proc.thread.scheduleInstallProvider(cpi);
9733                                 } catch (RemoteException e) {
9734                                 }
9735                             }
9736                         } else {
9737                             checkTime(startTime, "getContentProviderImpl: before start process");
9738                             proc = startProcessLocked(cpi.processName,
9739                                     cpr.appInfo, false, 0, "content provider",
9740                                     new ComponentName(cpi.applicationInfo.packageName,
9741                                             cpi.name), false, false, false);
9742                             checkTime(startTime, "getContentProviderImpl: after start process");
9743                             if (proc == null) {
9744                                 Slog.w(TAG, "Unable to launch app "
9745                                         + cpi.applicationInfo.packageName + "/"
9746                                         + cpi.applicationInfo.uid + " for provider "
9747                                         + name + ": process is bad");
9748                                 return null;
9749                             }
9750                         }
9751                         cpr.launchingApp = proc;
9752                         mLaunchingProviders.add(cpr);
9753                     } finally {
9754                         Binder.restoreCallingIdentity(origId);
9755                     }
9756                 }
9757
9758                 checkTime(startTime, "getContentProviderImpl: updating data structures");
9759
9760                 // Make sure the provider is published (the same provider class
9761                 // may be published under multiple names).
9762                 if (firstClass) {
9763                     mProviderMap.putProviderByClass(comp, cpr);
9764                 }
9765
9766                 mProviderMap.putProviderByName(name, cpr);
9767                 conn = incProviderCountLocked(r, cpr, token, stable);
9768                 if (conn != null) {
9769                     conn.waiting = true;
9770                 }
9771             }
9772             checkTime(startTime, "getContentProviderImpl: done!");
9773         }
9774
9775         // Wait for the provider to be published...
9776         synchronized (cpr) {
9777             while (cpr.provider == null) {
9778                 if (cpr.launchingApp == null) {
9779                     Slog.w(TAG, "Unable to launch app "
9780                             + cpi.applicationInfo.packageName + "/"
9781                             + cpi.applicationInfo.uid + " for provider "
9782                             + name + ": launching app became null");
9783                     EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
9784                             UserHandle.getUserId(cpi.applicationInfo.uid),
9785                             cpi.applicationInfo.packageName,
9786                             cpi.applicationInfo.uid, name);
9787                     return null;
9788                 }
9789                 try {
9790                     if (DEBUG_MU) Slog.v(TAG_MU,
9791                             "Waiting to start provider " + cpr
9792                             + " launchingApp=" + cpr.launchingApp);
9793                     if (conn != null) {
9794                         conn.waiting = true;
9795                     }
9796                     cpr.wait();
9797                 } catch (InterruptedException ex) {
9798                 } finally {
9799                     if (conn != null) {
9800                         conn.waiting = false;
9801                     }
9802                 }
9803             }
9804         }
9805         return cpr != null ? cpr.newHolder(conn) : null;
9806     }
9807
9808     @Override
9809     public final ContentProviderHolder getContentProvider(
9810             IApplicationThread caller, String name, int userId, boolean stable) {
9811         enforceNotIsolatedCaller("getContentProvider");
9812         if (caller == null) {
9813             String msg = "null IApplicationThread when getting content provider "
9814                     + name;
9815             Slog.w(TAG, msg);
9816             throw new SecurityException(msg);
9817         }
9818         // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
9819         // with cross-user grant.
9820         return getContentProviderImpl(caller, name, null, stable, userId);
9821     }
9822
9823     public ContentProviderHolder getContentProviderExternal(
9824             String name, int userId, IBinder token) {
9825         enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9826             "Do not have permission in call getContentProviderExternal()");
9827         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
9828                 false, ALLOW_FULL_ONLY, "getContentProvider", null);
9829         return getContentProviderExternalUnchecked(name, token, userId);
9830     }
9831
9832     private ContentProviderHolder getContentProviderExternalUnchecked(String name,
9833             IBinder token, int userId) {
9834         return getContentProviderImpl(null, name, token, true, userId);
9835     }
9836
9837     /**
9838      * Drop a content provider from a ProcessRecord's bookkeeping
9839      */
9840     public void removeContentProvider(IBinder connection, boolean stable) {
9841         enforceNotIsolatedCaller("removeContentProvider");
9842         long ident = Binder.clearCallingIdentity();
9843         try {
9844             synchronized (this) {
9845                 ContentProviderConnection conn;
9846                 try {
9847                     conn = (ContentProviderConnection)connection;
9848                 } catch (ClassCastException e) {
9849                     String msg ="removeContentProvider: " + connection
9850                             + " not a ContentProviderConnection";
9851                     Slog.w(TAG, msg);
9852                     throw new IllegalArgumentException(msg);
9853                 }
9854                 if (conn == null) {
9855                     throw new NullPointerException("connection is null");
9856                 }
9857                 if (decProviderCountLocked(conn, null, null, stable)) {
9858                     updateOomAdjLocked();
9859                 }
9860             }
9861         } finally {
9862             Binder.restoreCallingIdentity(ident);
9863         }
9864     }
9865
9866     public void removeContentProviderExternal(String name, IBinder token) {
9867         enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9868             "Do not have permission in call removeContentProviderExternal()");
9869         int userId = UserHandle.getCallingUserId();
9870         long ident = Binder.clearCallingIdentity();
9871         try {
9872             removeContentProviderExternalUnchecked(name, token, userId);
9873         } finally {
9874             Binder.restoreCallingIdentity(ident);
9875         }
9876     }
9877
9878     private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
9879         synchronized (this) {
9880             ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
9881             if(cpr == null) {
9882                 //remove from mProvidersByClass
9883                 if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
9884                 return;
9885             }
9886
9887             //update content provider record entry info
9888             ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
9889             ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
9890             if (localCpr.hasExternalProcessHandles()) {
9891                 if (localCpr.removeExternalProcessHandleLocked(token)) {
9892                     updateOomAdjLocked();
9893                 } else {
9894                     Slog.e(TAG, "Attmpt to remove content provider " + localCpr
9895                             + " with no external reference for token: "
9896                             + token + ".");
9897                 }
9898             } else {
9899                 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
9900                         + " with no external references.");
9901             }
9902         }
9903     }
9904
9905     public final void publishContentProviders(IApplicationThread caller,
9906             List<ContentProviderHolder> providers) {
9907         if (providers == null) {
9908             return;
9909         }
9910
9911         enforceNotIsolatedCaller("publishContentProviders");
9912         synchronized (this) {
9913             final ProcessRecord r = getRecordForAppLocked(caller);
9914             if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
9915             if (r == null) {
9916                 throw new SecurityException(
9917                         "Unable to find app for caller " + caller
9918                       + " (pid=" + Binder.getCallingPid()
9919                       + ") when publishing content providers");
9920             }
9921
9922             final long origId = Binder.clearCallingIdentity();
9923
9924             final int N = providers.size();
9925             for (int i = 0; i < N; i++) {
9926                 ContentProviderHolder src = providers.get(i);
9927                 if (src == null || src.info == null || src.provider == null) {
9928                     continue;
9929                 }
9930                 ContentProviderRecord dst = r.pubProviders.get(src.info.name);
9931                 if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
9932                 if (dst != null) {
9933                     ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
9934                     mProviderMap.putProviderByClass(comp, dst);
9935                     String names[] = dst.info.authority.split(";");
9936                     for (int j = 0; j < names.length; j++) {
9937                         mProviderMap.putProviderByName(names[j], dst);
9938                     }
9939
9940                     int launchingCount = mLaunchingProviders.size();
9941                     int j;
9942                     boolean wasInLaunchingProviders = false;
9943                     for (j = 0; j < launchingCount; j++) {
9944                         if (mLaunchingProviders.get(j) == dst) {
9945                             mLaunchingProviders.remove(j);
9946                             wasInLaunchingProviders = true;
9947                             j--;
9948                             launchingCount--;
9949                         }
9950                     }
9951                     if (wasInLaunchingProviders) {
9952                         mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
9953                     }
9954                     synchronized (dst) {
9955                         dst.provider = src.provider;
9956                         dst.proc = r;
9957                         dst.notifyAll();
9958                     }
9959                     updateOomAdjLocked(r);
9960                     maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
9961                             src.info.authority);
9962                 }
9963             }
9964
9965             Binder.restoreCallingIdentity(origId);
9966         }
9967     }
9968
9969     public boolean refContentProvider(IBinder connection, int stable, int unstable) {
9970         ContentProviderConnection conn;
9971         try {
9972             conn = (ContentProviderConnection)connection;
9973         } catch (ClassCastException e) {
9974             String msg ="refContentProvider: " + connection
9975                     + " not a ContentProviderConnection";
9976             Slog.w(TAG, msg);
9977             throw new IllegalArgumentException(msg);
9978         }
9979         if (conn == null) {
9980             throw new NullPointerException("connection is null");
9981         }
9982
9983         synchronized (this) {
9984             if (stable > 0) {
9985                 conn.numStableIncs += stable;
9986             }
9987             stable = conn.stableCount + stable;
9988             if (stable < 0) {
9989                 throw new IllegalStateException("stableCount < 0: " + stable);
9990             }
9991
9992             if (unstable > 0) {
9993                 conn.numUnstableIncs += unstable;
9994             }
9995             unstable = conn.unstableCount + unstable;
9996             if (unstable < 0) {
9997                 throw new IllegalStateException("unstableCount < 0: " + unstable);
9998             }
9999
10000             if ((stable+unstable) <= 0) {
10001                 throw new IllegalStateException("ref counts can't go to zero here: stable="
10002                         + stable + " unstable=" + unstable);
10003             }
10004             conn.stableCount = stable;
10005             conn.unstableCount = unstable;
10006             return !conn.dead;
10007         }
10008     }
10009
10010     public void unstableProviderDied(IBinder connection) {
10011         ContentProviderConnection conn;
10012         try {
10013             conn = (ContentProviderConnection)connection;
10014         } catch (ClassCastException e) {
10015             String msg ="refContentProvider: " + connection
10016                     + " not a ContentProviderConnection";
10017             Slog.w(TAG, msg);
10018             throw new IllegalArgumentException(msg);
10019         }
10020         if (conn == null) {
10021             throw new NullPointerException("connection is null");
10022         }
10023
10024         // Safely retrieve the content provider associated with the connection.
10025         IContentProvider provider;
10026         synchronized (this) {
10027             provider = conn.provider.provider;
10028         }
10029
10030         if (provider == null) {
10031             // Um, yeah, we're way ahead of you.
10032             return;
10033         }
10034
10035         // Make sure the caller is being honest with us.
10036         if (provider.asBinder().pingBinder()) {
10037             // Er, no, still looks good to us.
10038             synchronized (this) {
10039                 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
10040                         + " says " + conn + " died, but we don't agree");
10041                 return;
10042             }
10043         }
10044
10045         // Well look at that!  It's dead!
10046         synchronized (this) {
10047             if (conn.provider.provider != provider) {
10048                 // But something changed...  good enough.
10049                 return;
10050             }
10051
10052             ProcessRecord proc = conn.provider.proc;
10053             if (proc == null || proc.thread == null) {
10054                 // Seems like the process is already cleaned up.
10055                 return;
10056             }
10057
10058             // As far as we're concerned, this is just like receiving a
10059             // death notification...  just a bit prematurely.
10060             Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
10061                     + ") early provider death");
10062             final long ident = Binder.clearCallingIdentity();
10063             try {
10064                 appDiedLocked(proc);
10065             } finally {
10066                 Binder.restoreCallingIdentity(ident);
10067             }
10068         }
10069     }
10070
10071     @Override
10072     public void appNotRespondingViaProvider(IBinder connection) {
10073         enforceCallingPermission(
10074                 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
10075
10076         final ContentProviderConnection conn = (ContentProviderConnection) connection;
10077         if (conn == null) {
10078             Slog.w(TAG, "ContentProviderConnection is null");
10079             return;
10080         }
10081
10082         final ProcessRecord host = conn.provider.proc;
10083         if (host == null) {
10084             Slog.w(TAG, "Failed to find hosting ProcessRecord");
10085             return;
10086         }
10087
10088         final long token = Binder.clearCallingIdentity();
10089         try {
10090             appNotResponding(host, null, null, false, "ContentProvider not responding");
10091         } finally {
10092             Binder.restoreCallingIdentity(token);
10093         }
10094     }
10095
10096     public final void installSystemProviders() {
10097         List<ProviderInfo> providers;
10098         synchronized (this) {
10099             ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
10100             providers = generateApplicationProvidersLocked(app);
10101             if (providers != null) {
10102                 for (int i=providers.size()-1; i>=0; i--) {
10103                     ProviderInfo pi = (ProviderInfo)providers.get(i);
10104                     if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
10105                         Slog.w(TAG, "Not installing system proc provider " + pi.name
10106                                 + ": not system .apk");
10107                         providers.remove(i);
10108                     }
10109                 }
10110             }
10111         }
10112         if (providers != null) {
10113             mSystemThread.installSystemProviders(providers);
10114         }
10115
10116         mCoreSettingsObserver = new CoreSettingsObserver(this);
10117
10118         //mUsageStatsService.monitorPackages();
10119     }
10120
10121     /**
10122      * Allows apps to retrieve the MIME type of a URI.
10123      * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
10124      * users, then it does not need permission to access the ContentProvider.
10125      * Either, it needs cross-user uri grants.
10126      *
10127      * CTS tests for this functionality can be run with "runtest cts-appsecurity".
10128      *
10129      * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
10130      *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
10131      */
10132     public String getProviderMimeType(Uri uri, int userId) {
10133         enforceNotIsolatedCaller("getProviderMimeType");
10134         final String name = uri.getAuthority();
10135         int callingUid = Binder.getCallingUid();
10136         int callingPid = Binder.getCallingPid();
10137         long ident = 0;
10138         boolean clearedIdentity = false;
10139         userId = unsafeConvertIncomingUser(userId);
10140         if (canClearIdentity(callingPid, callingUid, userId)) {
10141             clearedIdentity = true;
10142             ident = Binder.clearCallingIdentity();
10143         }
10144         ContentProviderHolder holder = null;
10145         try {
10146             holder = getContentProviderExternalUnchecked(name, null, userId);
10147             if (holder != null) {
10148                 return holder.provider.getType(uri);
10149             }
10150         } catch (RemoteException e) {
10151             Log.w(TAG, "Content provider dead retrieving " + uri, e);
10152             return null;
10153         } finally {
10154             // We need to clear the identity to call removeContentProviderExternalUnchecked
10155             if (!clearedIdentity) {
10156                 ident = Binder.clearCallingIdentity();
10157             }
10158             try {
10159                 if (holder != null) {
10160                     removeContentProviderExternalUnchecked(name, null, userId);
10161                 }
10162             } finally {
10163                 Binder.restoreCallingIdentity(ident);
10164             }
10165         }
10166
10167         return null;
10168     }
10169
10170     private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
10171         if (UserHandle.getUserId(callingUid) == userId) {
10172             return true;
10173         }
10174         if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
10175                 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
10176                 || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
10177                 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
10178                 return true;
10179         }
10180         return false;
10181     }
10182
10183     // =========================================================
10184     // GLOBAL MANAGEMENT
10185     // =========================================================
10186
10187     final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
10188             boolean isolated, int isolatedUid) {
10189         String proc = customProcess != null ? customProcess : info.processName;
10190         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10191         final int userId = UserHandle.getUserId(info.uid);
10192         int uid = info.uid;
10193         if (isolated) {
10194             if (isolatedUid == 0) {
10195                 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
10196                 while (true) {
10197                     if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
10198                             || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
10199                         mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
10200                     }
10201                     uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
10202                     mNextIsolatedProcessUid++;
10203                     if (mIsolatedProcesses.indexOfKey(uid) < 0) {
10204                         // No process for this uid, use it.
10205                         break;
10206                     }
10207                     stepsLeft--;
10208                     if (stepsLeft <= 0) {
10209                         return null;
10210                     }
10211                 }
10212             } else {
10213                 // Special case for startIsolatedProcess (internal only), where
10214                 // the uid of the isolated process is specified by the caller.
10215                 uid = isolatedUid;
10216             }
10217         }
10218         final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
10219         if (!mBooted && !mBooting
10220                 && userId == UserHandle.USER_OWNER
10221                 && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
10222             r.persistent = true;
10223         }
10224         addProcessNameLocked(r);
10225         return r;
10226     }
10227
10228     final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
10229             String abiOverride) {
10230         ProcessRecord app;
10231         if (!isolated) {
10232             app = getProcessRecordLocked(info.processName, info.uid, true);
10233         } else {
10234             app = null;
10235         }
10236
10237         if (app == null) {
10238             app = newProcessRecordLocked(info, null, isolated, 0);
10239             updateLruProcessLocked(app, false, null);
10240             updateOomAdjLocked();
10241         }
10242
10243         // This package really, really can not be stopped.
10244         try {
10245             AppGlobals.getPackageManager().setPackageStoppedState(
10246                     info.packageName, false, UserHandle.getUserId(app.uid));
10247         } catch (RemoteException e) {
10248         } catch (IllegalArgumentException e) {
10249             Slog.w(TAG, "Failed trying to unstop package "
10250                     + info.packageName + ": " + e);
10251         }
10252
10253         if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
10254             app.persistent = true;
10255             app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
10256         }
10257         if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
10258             mPersistentStartingProcesses.add(app);
10259             startProcessLocked(app, "added application", app.processName, abiOverride,
10260                     null /* entryPoint */, null /* entryPointArgs */);
10261         }
10262
10263         return app;
10264     }
10265
10266     public void unhandledBack() {
10267         enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
10268                 "unhandledBack()");
10269
10270         synchronized(this) {
10271             final long origId = Binder.clearCallingIdentity();
10272             try {
10273                 getFocusedStack().unhandledBackLocked();
10274             } finally {
10275                 Binder.restoreCallingIdentity(origId);
10276             }
10277         }
10278     }
10279
10280     public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
10281         enforceNotIsolatedCaller("openContentUri");
10282         final int userId = UserHandle.getCallingUserId();
10283         String name = uri.getAuthority();
10284         ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
10285         ParcelFileDescriptor pfd = null;
10286         if (cph != null) {
10287             // We record the binder invoker's uid in thread-local storage before
10288             // going to the content provider to open the file.  Later, in the code
10289             // that handles all permissions checks, we look for this uid and use
10290             // that rather than the Activity Manager's own uid.  The effect is that
10291             // we do the check against the caller's permissions even though it looks
10292             // to the content provider like the Activity Manager itself is making
10293             // the request.
10294             Binder token = new Binder();
10295             sCallerIdentity.set(new Identity(
10296                     token, Binder.getCallingPid(), Binder.getCallingUid()));
10297             try {
10298                 pfd = cph.provider.openFile(null, uri, "r", null, token);
10299             } catch (FileNotFoundException e) {
10300                 // do nothing; pfd will be returned null
10301             } finally {
10302                 // Ensure that whatever happens, we clean up the identity state
10303                 sCallerIdentity.remove();
10304                 // Ensure we're done with the provider.
10305                 removeContentProviderExternalUnchecked(name, null, userId);
10306             }
10307         } else {
10308             Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
10309         }
10310         return pfd;
10311     }
10312
10313     // Actually is sleeping or shutting down or whatever else in the future
10314     // is an inactive state.
10315     public boolean isSleepingOrShuttingDown() {
10316         return isSleeping() || mShuttingDown;
10317     }
10318
10319     public boolean isSleeping() {
10320         return mSleeping;
10321     }
10322
10323     void onWakefulnessChanged(int wakefulness) {
10324         synchronized(this) {
10325             mWakefulness = wakefulness;
10326             updateSleepIfNeededLocked();
10327         }
10328     }
10329
10330     void finishRunningVoiceLocked() {
10331         if (mRunningVoice != null) {
10332             mRunningVoice = null;
10333             mVoiceWakeLock.release();
10334             updateSleepIfNeededLocked();
10335         }
10336     }
10337
10338     void startTimeTrackingFocusedActivityLocked() {
10339         if (!mSleeping && mCurAppTimeTracker != null && mFocusedActivity != null) {
10340             mCurAppTimeTracker.start(mFocusedActivity.packageName);
10341         }
10342     }
10343
10344     void updateSleepIfNeededLocked() {
10345         if (mSleeping && !shouldSleepLocked()) {
10346             mSleeping = false;
10347             startTimeTrackingFocusedActivityLocked();
10348             mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
10349             mStackSupervisor.comeOutOfSleepIfNeededLocked();
10350             updateOomAdjLocked();
10351         } else if (!mSleeping && shouldSleepLocked()) {
10352             mSleeping = true;
10353             if (mCurAppTimeTracker != null) {
10354                 mCurAppTimeTracker.stop();
10355             }
10356             mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
10357             mStackSupervisor.goingToSleepLocked();
10358             updateOomAdjLocked();
10359
10360             // Initialize the wake times of all processes.
10361             checkExcessivePowerUsageLocked(false);
10362             mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
10363             Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
10364             mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
10365         }
10366     }
10367
10368     private boolean shouldSleepLocked() {
10369         // Resume applications while running a voice interactor.
10370         if (mRunningVoice != null) {
10371             return false;
10372         }
10373
10374         // TODO: Transform the lock screen state into a sleep token instead.
10375         switch (mWakefulness) {
10376             case PowerManagerInternal.WAKEFULNESS_AWAKE:
10377             case PowerManagerInternal.WAKEFULNESS_DREAMING:
10378             case PowerManagerInternal.WAKEFULNESS_DOZING:
10379                 // Pause applications whenever the lock screen is shown or any sleep
10380                 // tokens have been acquired.
10381                 return (mLockScreenShown != LOCK_SCREEN_HIDDEN || !mSleepTokens.isEmpty());
10382             case PowerManagerInternal.WAKEFULNESS_ASLEEP:
10383             default:
10384                 // If we're asleep then pause applications unconditionally.
10385                 return true;
10386         }
10387     }
10388
10389     /** Pokes the task persister. */
10390     void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
10391         if (task != null && task.stack != null && task.stack.isHomeStack()) {
10392             // Never persist the home stack.
10393             return;
10394         }
10395         mTaskPersister.wakeup(task, flush);
10396     }
10397
10398     /** Notifies all listeners when the task stack has changed. */
10399     void notifyTaskStackChangedLocked() {
10400         mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
10401         Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
10402         mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
10403     }
10404
10405     @Override
10406     public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
10407         mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
10408     }
10409
10410     @Override
10411     public boolean shutdown(int timeout) {
10412         if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
10413                 != PackageManager.PERMISSION_GRANTED) {
10414             throw new SecurityException("Requires permission "
10415                     + android.Manifest.permission.SHUTDOWN);
10416         }
10417
10418         boolean timedout = false;
10419
10420         synchronized(this) {
10421             mShuttingDown = true;
10422             updateEventDispatchingLocked();
10423             timedout = mStackSupervisor.shutdownLocked(timeout);
10424         }
10425
10426         mAppOpsService.shutdown();
10427         if (mUsageStatsService != null) {
10428             mUsageStatsService.prepareShutdown();
10429         }
10430         mBatteryStatsService.shutdown();
10431         synchronized (this) {
10432             mProcessStats.shutdownLocked();
10433             notifyTaskPersisterLocked(null, true);
10434         }
10435
10436         return timedout;
10437     }
10438
10439     public final void activitySlept(IBinder token) {
10440         if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
10441
10442         final long origId = Binder.clearCallingIdentity();
10443
10444         synchronized (this) {
10445             final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10446             if (r != null) {
10447                 mStackSupervisor.activitySleptLocked(r);
10448             }
10449         }
10450
10451         Binder.restoreCallingIdentity(origId);
10452     }
10453
10454     private String lockScreenShownToString() {
10455         switch (mLockScreenShown) {
10456             case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
10457             case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
10458             case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
10459             default: return "Unknown=" + mLockScreenShown;
10460         }
10461     }
10462
10463     void logLockScreen(String msg) {
10464         if (DEBUG_LOCKSCREEN) Slog.d(TAG_LOCKSCREEN, Debug.getCallers(2) + ":" + msg
10465                 + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
10466                 + PowerManagerInternal.wakefulnessToString(mWakefulness)
10467                 + " mSleeping=" + mSleeping);
10468     }
10469
10470     void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
10471         mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
10472         if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
10473             boolean wasRunningVoice = mRunningVoice != null;
10474             mRunningVoice = session;
10475             if (!wasRunningVoice) {
10476                 mVoiceWakeLock.acquire();
10477                 updateSleepIfNeededLocked();
10478             }
10479         }
10480     }
10481
10482     private void updateEventDispatchingLocked() {
10483         mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
10484     }
10485
10486     public void setLockScreenShown(boolean shown) {
10487         if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
10488                 != PackageManager.PERMISSION_GRANTED) {
10489             throw new SecurityException("Requires permission "
10490                     + android.Manifest.permission.DEVICE_POWER);
10491         }
10492
10493         synchronized(this) {
10494             long ident = Binder.clearCallingIdentity();
10495             try {
10496                 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
10497                 mLockScreenShown = shown ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
10498                 updateSleepIfNeededLocked();
10499             } finally {
10500                 Binder.restoreCallingIdentity(ident);
10501             }
10502         }
10503     }
10504
10505     @Override
10506     public void stopAppSwitches() {
10507         if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10508                 != PackageManager.PERMISSION_GRANTED) {
10509             throw new SecurityException("Requires permission "
10510                     + android.Manifest.permission.STOP_APP_SWITCHES);
10511         }
10512
10513         synchronized(this) {
10514             mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
10515                     + APP_SWITCH_DELAY_TIME;
10516             mDidAppSwitch = false;
10517             mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10518             Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10519             mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
10520         }
10521     }
10522
10523     public void resumeAppSwitches() {
10524         if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10525                 != PackageManager.PERMISSION_GRANTED) {
10526             throw new SecurityException("Requires permission "
10527                     + android.Manifest.permission.STOP_APP_SWITCHES);
10528         }
10529
10530         synchronized(this) {
10531             // Note that we don't execute any pending app switches... we will
10532             // let those wait until either the timeout, or the next start
10533             // activity request.
10534             mAppSwitchesAllowedTime = 0;
10535         }
10536     }
10537
10538     boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
10539             int callingPid, int callingUid, String name) {
10540         if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
10541             return true;
10542         }
10543
10544         int perm = checkComponentPermission(
10545                 android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
10546                 sourceUid, -1, true);
10547         if (perm == PackageManager.PERMISSION_GRANTED) {
10548             return true;
10549         }
10550
10551         // If the actual IPC caller is different from the logical source, then
10552         // also see if they are allowed to control app switches.
10553         if (callingUid != -1 && callingUid != sourceUid) {
10554             perm = checkComponentPermission(
10555                     android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
10556                     callingUid, -1, true);
10557             if (perm == PackageManager.PERMISSION_GRANTED) {
10558                 return true;
10559             }
10560         }
10561
10562         Slog.w(TAG, name + " request from " + sourceUid + " stopped");
10563         return false;
10564     }
10565
10566     public void setDebugApp(String packageName, boolean waitForDebugger,
10567             boolean persistent) {
10568         enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
10569                 "setDebugApp()");
10570
10571         long ident = Binder.clearCallingIdentity();
10572         try {
10573             // Note that this is not really thread safe if there are multiple
10574             // callers into it at the same time, but that's not a situation we
10575             // care about.
10576             if (persistent) {
10577                 final ContentResolver resolver = mContext.getContentResolver();
10578                 Settings.Global.putString(
10579                     resolver, Settings.Global.DEBUG_APP,
10580                     packageName);
10581                 Settings.Global.putInt(
10582                     resolver, Settings.Global.WAIT_FOR_DEBUGGER,
10583                     waitForDebugger ? 1 : 0);
10584             }
10585
10586             synchronized (this) {
10587                 if (!persistent) {
10588                     mOrigDebugApp = mDebugApp;
10589                     mOrigWaitForDebugger = mWaitForDebugger;
10590                 }
10591                 mDebugApp = packageName;
10592                 mWaitForDebugger = waitForDebugger;
10593                 mDebugTransient = !persistent;
10594                 if (packageName != null) {
10595                     forceStopPackageLocked(packageName, -1, false, false, true, true,
10596                             false, UserHandle.USER_ALL, "set debug app");
10597                 }
10598             }
10599         } finally {
10600             Binder.restoreCallingIdentity(ident);
10601         }
10602     }
10603
10604     void setOpenGlTraceApp(ApplicationInfo app, String processName) {
10605         synchronized (this) {
10606             boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10607             if (!isDebuggable) {
10608                 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10609                     throw new SecurityException("Process not debuggable: " + app.packageName);
10610                 }
10611             }
10612
10613             mOpenGlTraceApp = processName;
10614         }
10615     }
10616
10617     void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
10618         synchronized (this) {
10619             boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10620             if (!isDebuggable) {
10621                 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10622                     throw new SecurityException("Process not debuggable: " + app.packageName);
10623                 }
10624             }
10625             mProfileApp = processName;
10626             mProfileFile = profilerInfo.profileFile;
10627             if (mProfileFd != null) {
10628                 try {
10629                     mProfileFd.close();
10630                 } catch (IOException e) {
10631                 }
10632                 mProfileFd = null;
10633             }
10634             mProfileFd = profilerInfo.profileFd;
10635             mSamplingInterval = profilerInfo.samplingInterval;
10636             mAutoStopProfiler = profilerInfo.autoStopProfiler;
10637             mProfileType = 0;
10638         }
10639     }
10640
10641     @Override
10642     public void setAlwaysFinish(boolean enabled) {
10643         enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
10644                 "setAlwaysFinish()");
10645
10646         Settings.Global.putInt(
10647                 mContext.getContentResolver(),
10648                 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
10649
10650         synchronized (this) {
10651             mAlwaysFinishActivities = enabled;
10652         }
10653     }
10654
10655     @Override
10656     public void setActivityController(IActivityController controller) {
10657         enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10658                 "setActivityController()");
10659         synchronized (this) {
10660             mController = controller;
10661             Watchdog.getInstance().setActivityController(controller);
10662         }
10663     }
10664
10665     @Override
10666     public void setUserIsMonkey(boolean userIsMonkey) {
10667         synchronized (this) {
10668             synchronized (mPidsSelfLocked) {
10669                 final int callingPid = Binder.getCallingPid();
10670                 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
10671                 if (precessRecord == null) {
10672                     throw new SecurityException("Unknown process: " + callingPid);
10673                 }
10674                 if (precessRecord.instrumentationUiAutomationConnection  == null) {
10675                     throw new SecurityException("Only an instrumentation process "
10676                             + "with a UiAutomation can call setUserIsMonkey");
10677                 }
10678             }
10679             mUserIsMonkey = userIsMonkey;
10680         }
10681     }
10682
10683     @Override
10684     public boolean isUserAMonkey() {
10685         synchronized (this) {
10686             // If there is a controller also implies the user is a monkey.
10687             return (mUserIsMonkey || mController != null);
10688         }
10689     }
10690
10691     public void requestBugReport() {
10692         enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
10693         SystemProperties.set("ctl.start", "bugreport");
10694     }
10695
10696     public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
10697         return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
10698     }
10699
10700     public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
10701         if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
10702             return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
10703         }
10704         return KEY_DISPATCHING_TIMEOUT;
10705     }
10706
10707     @Override
10708     public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
10709         if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10710                 != PackageManager.PERMISSION_GRANTED) {
10711             throw new SecurityException("Requires permission "
10712                     + android.Manifest.permission.FILTER_EVENTS);
10713         }
10714         ProcessRecord proc;
10715         long timeout;
10716         synchronized (this) {
10717             synchronized (mPidsSelfLocked) {
10718                 proc = mPidsSelfLocked.get(pid);
10719             }
10720             timeout = getInputDispatchingTimeoutLocked(proc);
10721         }
10722
10723         if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
10724             return -1;
10725         }
10726
10727         return timeout;
10728     }
10729
10730     /**
10731      * Handle input dispatching timeouts.
10732      * Returns whether input dispatching should be aborted or not.
10733      */
10734     public boolean inputDispatchingTimedOut(final ProcessRecord proc,
10735             final ActivityRecord activity, final ActivityRecord parent,
10736             final boolean aboveSystem, String reason) {
10737         if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10738                 != PackageManager.PERMISSION_GRANTED) {
10739             throw new SecurityException("Requires permission "
10740                     + android.Manifest.permission.FILTER_EVENTS);
10741         }
10742
10743         final String annotation;
10744         if (reason == null) {
10745             annotation = "Input dispatching timed out";
10746         } else {
10747             annotation = "Input dispatching timed out (" + reason + ")";
10748         }
10749
10750         if (proc != null) {
10751             synchronized (this) {
10752                 if (proc.debugging) {
10753                     return false;
10754                 }
10755
10756                 if (mDidDexOpt) {
10757                     // Give more time since we were dexopting.
10758                     mDidDexOpt = false;
10759                     return false;
10760                 }
10761
10762                 if (proc.instrumentationClass != null) {
10763                     Bundle info = new Bundle();
10764                     info.putString("shortMsg", "keyDispatchingTimedOut");
10765                     info.putString("longMsg", annotation);
10766                     finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
10767                     return true;
10768                 }
10769             }
10770             mHandler.post(new Runnable() {
10771                 @Override
10772                 public void run() {
10773                     appNotResponding(proc, activity, parent, aboveSystem, annotation);
10774                 }
10775             });
10776         }
10777
10778         return true;
10779     }
10780
10781     @Override
10782     public Bundle getAssistContextExtras(int requestType) {
10783         PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
10784                 null, UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT);
10785         if (pae == null) {
10786             return null;
10787         }
10788         synchronized (pae) {
10789             while (!pae.haveResult) {
10790                 try {
10791                     pae.wait();
10792                 } catch (InterruptedException e) {
10793                 }
10794             }
10795         }
10796         synchronized (this) {
10797             buildAssistBundleLocked(pae, pae.result);
10798             mPendingAssistExtras.remove(pae);
10799             mUiHandler.removeCallbacks(pae);
10800         }
10801         return pae.extras;
10802     }
10803
10804     @Override
10805     public boolean isAssistDataAllowedOnCurrentActivity() {
10806         int userId = mCurrentUserId;
10807         synchronized (this) {
10808             ActivityRecord activity = getFocusedStack().topActivity();
10809             if (activity == null) {
10810                 return false;
10811             }
10812             userId = activity.userId;
10813         }
10814         DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
10815                 Context.DEVICE_POLICY_SERVICE);
10816         return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
10817     }
10818
10819     @Override
10820     public boolean showAssistFromActivity(IBinder token, Bundle args) {
10821         long ident = Binder.clearCallingIdentity();
10822         try {
10823             synchronized (this) {
10824                 ActivityRecord caller = ActivityRecord.forTokenLocked(token);
10825                 ActivityRecord top = getFocusedStack().topActivity();
10826                 if (top != caller) {
10827                     Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
10828                             + " is not current top " + top);
10829                     return false;
10830                 }
10831                 if (!top.nowVisible) {
10832                     Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
10833                             + " is not visible");
10834                     return false;
10835                 }
10836             }
10837             AssistUtils utils = new AssistUtils(mContext);
10838             return utils.showSessionForActiveService(args,
10839                     VoiceInteractionSession.SHOW_SOURCE_APPLICATION, null, token);
10840         } finally {
10841             Binder.restoreCallingIdentity(ident);
10842         }
10843     }
10844
10845     @Override
10846     public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
10847             IBinder activityToken) {
10848         return enqueueAssistContext(requestType, null, null, receiver, activityToken,
10849                 UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_LONG_TIMEOUT) != null;
10850     }
10851
10852     private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
10853             IResultReceiver receiver, IBinder activityToken, int userHandle, Bundle args,
10854             long timeout) {
10855         enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
10856                 "enqueueAssistContext()");
10857         synchronized (this) {
10858             ActivityRecord activity = getFocusedStack().topActivity();
10859             if (activity == null) {
10860                 Slog.w(TAG, "getAssistContextExtras failed: no top activity");
10861                 return null;
10862             }
10863             if (activity.app == null || activity.app.thread == null) {
10864                 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
10865                 return null;
10866             }
10867             if (activityToken != null) {
10868                 ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
10869                 if (activity != caller) {
10870                     Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
10871                             + " is not current top " + activity);
10872                     return null;
10873                 }
10874             }
10875             PendingAssistExtras pae;
10876             Bundle extras = new Bundle();
10877             if (args != null) {
10878                 extras.putAll(args);
10879             }
10880             extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
10881             extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
10882             pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, userHandle);
10883             try {
10884                 activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
10885                         requestType);
10886                 mPendingAssistExtras.add(pae);
10887                 mUiHandler.postDelayed(pae, timeout);
10888             } catch (RemoteException e) {
10889                 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
10890                 return null;
10891             }
10892             return pae;
10893         }
10894     }
10895
10896     void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
10897         IResultReceiver receiver;
10898         synchronized (this) {
10899             mPendingAssistExtras.remove(pae);
10900             receiver = pae.receiver;
10901         }
10902         if (receiver != null) {
10903             // Caller wants result sent back to them.
10904             try {
10905                 pae.receiver.send(0, null);
10906             } catch (RemoteException e) {
10907             }
10908         }
10909     }
10910
10911     private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
10912         if (result != null) {
10913             pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
10914         }
10915         if (pae.hint != null) {
10916             pae.extras.putBoolean(pae.hint, true);
10917         }
10918     }
10919
10920     public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
10921             AssistContent content, Uri referrer) {
10922         PendingAssistExtras pae = (PendingAssistExtras)token;
10923         synchronized (pae) {
10924             pae.result = extras;
10925             pae.structure = structure;
10926             pae.content = content;
10927             if (referrer != null) {
10928                 pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
10929             }
10930             pae.haveResult = true;
10931             pae.notifyAll();
10932             if (pae.intent == null && pae.receiver == null) {
10933                 // Caller is just waiting for the result.
10934                 return;
10935             }
10936         }
10937
10938         // We are now ready to launch the assist activity.
10939         IResultReceiver sendReceiver = null;
10940         Bundle sendBundle = null;
10941         synchronized (this) {
10942             buildAssistBundleLocked(pae, extras);
10943             boolean exists = mPendingAssistExtras.remove(pae);
10944             mUiHandler.removeCallbacks(pae);
10945             if (!exists) {
10946                 // Timed out.
10947                 return;
10948             }
10949             if ((sendReceiver=pae.receiver) != null) {
10950                 // Caller wants result sent back to them.
10951                 sendBundle = new Bundle();
10952                 sendBundle.putBundle("data", pae.extras);
10953                 sendBundle.putParcelable("structure", pae.structure);
10954                 sendBundle.putParcelable("content", pae.content);
10955             }
10956         }
10957         if (sendReceiver != null) {
10958             try {
10959                 sendReceiver.send(0, sendBundle);
10960             } catch (RemoteException e) {
10961             }
10962             return;
10963         }
10964
10965         long ident = Binder.clearCallingIdentity();
10966         try {
10967             pae.intent.replaceExtras(pae.extras);
10968             pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10969                     | Intent.FLAG_ACTIVITY_SINGLE_TOP
10970                     | Intent.FLAG_ACTIVITY_CLEAR_TOP);
10971             closeSystemDialogs("assist");
10972             try {
10973                 mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
10974             } catch (ActivityNotFoundException e) {
10975                 Slog.w(TAG, "No activity to handle assist action.", e);
10976             }
10977         } finally {
10978             Binder.restoreCallingIdentity(ident);
10979         }
10980     }
10981
10982     public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
10983             Bundle args) {
10984         return enqueueAssistContext(requestType, intent, hint, null, null, userHandle, args,
10985                 PENDING_ASSIST_EXTRAS_TIMEOUT) != null;
10986     }
10987
10988     public void registerProcessObserver(IProcessObserver observer) {
10989         enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10990                 "registerProcessObserver()");
10991         synchronized (this) {
10992             mProcessObservers.register(observer);
10993         }
10994     }
10995
10996     @Override
10997     public void unregisterProcessObserver(IProcessObserver observer) {
10998         synchronized (this) {
10999             mProcessObservers.unregister(observer);
11000         }
11001     }
11002
11003     public void registerUidObserver(IUidObserver observer) {
11004         enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
11005                 "registerUidObserver()");
11006         synchronized (this) {
11007             mUidObservers.register(observer);
11008         }
11009     }
11010
11011     @Override
11012     public void unregisterUidObserver(IUidObserver observer) {
11013         synchronized (this) {
11014             mUidObservers.unregister(observer);
11015         }
11016     }
11017
11018     @Override
11019     public boolean convertFromTranslucent(IBinder token) {
11020         final long origId = Binder.clearCallingIdentity();
11021         try {
11022             synchronized (this) {
11023                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11024                 if (r == null) {
11025                     return false;
11026                 }
11027                 final boolean translucentChanged = r.changeWindowTranslucency(true);
11028                 if (translucentChanged) {
11029                     r.task.stack.releaseBackgroundResources(r);
11030                     mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
11031                 }
11032                 mWindowManager.setAppFullscreen(token, true);
11033                 return translucentChanged;
11034             }
11035         } finally {
11036             Binder.restoreCallingIdentity(origId);
11037         }
11038     }
11039
11040     @Override
11041     public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
11042         final long origId = Binder.clearCallingIdentity();
11043         try {
11044             synchronized (this) {
11045                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11046                 if (r == null) {
11047                     return false;
11048                 }
11049                 int index = r.task.mActivities.lastIndexOf(r);
11050                 if (index > 0) {
11051                     ActivityRecord under = r.task.mActivities.get(index - 1);
11052                     under.returningOptions = options;
11053                 }
11054                 final boolean translucentChanged = r.changeWindowTranslucency(false);
11055                 if (translucentChanged) {
11056                     r.task.stack.convertActivityToTranslucent(r);
11057                 }
11058                 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
11059                 mWindowManager.setAppFullscreen(token, false);
11060                 return translucentChanged;
11061             }
11062         } finally {
11063             Binder.restoreCallingIdentity(origId);
11064         }
11065     }
11066
11067     @Override
11068     public boolean requestVisibleBehind(IBinder token, boolean visible) {
11069         final long origId = Binder.clearCallingIdentity();
11070         try {
11071             synchronized (this) {
11072                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11073                 if (r != null) {
11074                     return mStackSupervisor.requestVisibleBehindLocked(r, visible);
11075                 }
11076             }
11077             return false;
11078         } finally {
11079             Binder.restoreCallingIdentity(origId);
11080         }
11081     }
11082
11083     @Override
11084     public boolean isBackgroundVisibleBehind(IBinder token) {
11085         final long origId = Binder.clearCallingIdentity();
11086         try {
11087             synchronized (this) {
11088                 final ActivityStack stack = ActivityRecord.getStackLocked(token);
11089                 final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
11090                 if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
11091                         "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
11092                 return visible;
11093             }
11094         } finally {
11095             Binder.restoreCallingIdentity(origId);
11096         }
11097     }
11098
11099     @Override
11100     public ActivityOptions getActivityOptions(IBinder token) {
11101         final long origId = Binder.clearCallingIdentity();
11102         try {
11103             synchronized (this) {
11104                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11105                 if (r != null) {
11106                     final ActivityOptions activityOptions = r.pendingOptions;
11107                     r.pendingOptions = null;
11108                     return activityOptions;
11109                 }
11110                 return null;
11111             }
11112         } finally {
11113             Binder.restoreCallingIdentity(origId);
11114         }
11115     }
11116
11117     @Override
11118     public void setImmersive(IBinder token, boolean immersive) {
11119         synchronized(this) {
11120             final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11121             if (r == null) {
11122                 throw new IllegalArgumentException();
11123             }
11124             r.immersive = immersive;
11125
11126             // update associated state if we're frontmost
11127             if (r == mFocusedActivity) {
11128                 if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
11129                 applyUpdateLockStateLocked(r);
11130             }
11131         }
11132     }
11133
11134     @Override
11135     public boolean isImmersive(IBinder token) {
11136         synchronized (this) {
11137             ActivityRecord r = ActivityRecord.isInStackLocked(token);
11138             if (r == null) {
11139                 throw new IllegalArgumentException();
11140             }
11141             return r.immersive;
11142         }
11143     }
11144
11145     public boolean isTopActivityImmersive() {
11146         enforceNotIsolatedCaller("startActivity");
11147         synchronized (this) {
11148             ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
11149             return (r != null) ? r.immersive : false;
11150         }
11151     }
11152
11153     @Override
11154     public boolean isTopOfTask(IBinder token) {
11155         synchronized (this) {
11156             ActivityRecord r = ActivityRecord.isInStackLocked(token);
11157             if (r == null) {
11158                 throw new IllegalArgumentException();
11159             }
11160             return r.task.getTopActivity() == r;
11161         }
11162     }
11163
11164     public final void enterSafeMode() {
11165         synchronized(this) {
11166             // It only makes sense to do this before the system is ready
11167             // and started launching other packages.
11168             if (!mSystemReady) {
11169                 try {
11170                     AppGlobals.getPackageManager().enterSafeMode();
11171                 } catch (RemoteException e) {
11172                 }
11173             }
11174
11175             mSafeMode = true;
11176         }
11177     }
11178
11179     public final void showSafeModeOverlay() {
11180         View v = LayoutInflater.from(mContext).inflate(
11181                 com.android.internal.R.layout.safe_mode, null);
11182         WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
11183         lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
11184         lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
11185         lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
11186         lp.gravity = Gravity.BOTTOM | Gravity.START;
11187         lp.format = v.getBackground().getOpacity();
11188         lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
11189                 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
11190         lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
11191         ((WindowManager)mContext.getSystemService(
11192                 Context.WINDOW_SERVICE)).addView(v, lp);
11193     }
11194
11195     public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
11196         if (!(sender instanceof PendingIntentRecord)) {
11197             return;
11198         }
11199         final PendingIntentRecord rec = (PendingIntentRecord)sender;
11200         final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11201         synchronized (stats) {
11202             if (mBatteryStatsService.isOnBattery()) {
11203                 mBatteryStatsService.enforceCallingPermission();
11204                 int MY_UID = Binder.getCallingUid();
11205                 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
11206                 BatteryStatsImpl.Uid.Pkg pkg =
11207                     stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
11208                             sourcePkg != null ? sourcePkg : rec.key.packageName);
11209                 pkg.noteWakeupAlarmLocked(tag);
11210             }
11211         }
11212     }
11213
11214     public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
11215         if (!(sender instanceof PendingIntentRecord)) {
11216             return;
11217         }
11218         final PendingIntentRecord rec = (PendingIntentRecord)sender;
11219         final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11220         synchronized (stats) {
11221             mBatteryStatsService.enforceCallingPermission();
11222             int MY_UID = Binder.getCallingUid();
11223             int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
11224             mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
11225         }
11226     }
11227
11228     public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
11229         if (!(sender instanceof PendingIntentRecord)) {
11230             return;
11231         }
11232         final PendingIntentRecord rec = (PendingIntentRecord)sender;
11233         final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11234         synchronized (stats) {
11235             mBatteryStatsService.enforceCallingPermission();
11236             int MY_UID = Binder.getCallingUid();
11237             int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
11238             mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
11239         }
11240     }
11241
11242     public boolean killPids(int[] pids, String pReason, boolean secure) {
11243         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
11244             throw new SecurityException("killPids only available to the system");
11245         }
11246         String reason = (pReason == null) ? "Unknown" : pReason;
11247         // XXX Note: don't acquire main activity lock here, because the window
11248         // manager calls in with its locks held.
11249
11250         boolean killed = false;
11251         synchronized (mPidsSelfLocked) {
11252             int[] types = new int[pids.length];
11253             int worstType = 0;
11254             for (int i=0; i<pids.length; i++) {
11255                 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
11256                 if (proc != null) {
11257                     int type = proc.setAdj;
11258                     types[i] = type;
11259                     if (type > worstType) {
11260                         worstType = type;
11261                     }
11262                 }
11263             }
11264
11265             // If the worst oom_adj is somewhere in the cached proc LRU range,
11266             // then constrain it so we will kill all cached procs.
11267             if (worstType < ProcessList.CACHED_APP_MAX_ADJ
11268                     && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
11269                 worstType = ProcessList.CACHED_APP_MIN_ADJ;
11270             }
11271
11272             // If this is not a secure call, don't let it kill processes that
11273             // are important.
11274             if (!secure && worstType < ProcessList.SERVICE_ADJ) {
11275                 worstType = ProcessList.SERVICE_ADJ;
11276             }
11277
11278             Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
11279             for (int i=0; i<pids.length; i++) {
11280                 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
11281                 if (proc == null) {
11282                     continue;
11283                 }
11284                 int adj = proc.setAdj;
11285                 if (adj >= worstType && !proc.killedByAm) {
11286                     proc.kill(reason, true);
11287                     killed = true;
11288                 }
11289             }
11290         }
11291         return killed;
11292     }
11293
11294     @Override
11295     public void killUid(int appId, int userId, String reason) {
11296         enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
11297         synchronized (this) {
11298             final long identity = Binder.clearCallingIdentity();
11299             try {
11300                 killPackageProcessesLocked(null, appId, userId,
11301                         ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
11302                         reason != null ? reason : "kill uid");
11303             } finally {
11304                 Binder.restoreCallingIdentity(identity);
11305             }
11306         }
11307     }
11308
11309     @Override
11310     public boolean killProcessesBelowForeground(String reason) {
11311         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
11312             throw new SecurityException("killProcessesBelowForeground() only available to system");
11313         }
11314
11315         return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
11316     }
11317
11318     private boolean killProcessesBelowAdj(int belowAdj, String reason) {
11319         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
11320             throw new SecurityException("killProcessesBelowAdj() only available to system");
11321         }
11322
11323         boolean killed = false;
11324         synchronized (mPidsSelfLocked) {
11325             final int size = mPidsSelfLocked.size();
11326             for (int i = 0; i < size; i++) {
11327                 final int pid = mPidsSelfLocked.keyAt(i);
11328                 final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
11329                 if (proc == null) continue;
11330
11331                 final int adj = proc.setAdj;
11332                 if (adj > belowAdj && !proc.killedByAm) {
11333                     proc.kill(reason, true);
11334                     killed = true;
11335                 }
11336             }
11337         }
11338         return killed;
11339     }
11340
11341     @Override
11342     public void hang(final IBinder who, boolean allowRestart) {
11343         if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
11344                 != PackageManager.PERMISSION_GRANTED) {
11345             throw new SecurityException("Requires permission "
11346                     + android.Manifest.permission.SET_ACTIVITY_WATCHER);
11347         }
11348
11349         final IBinder.DeathRecipient death = new DeathRecipient() {
11350             @Override
11351             public void binderDied() {
11352                 synchronized (this) {
11353                     notifyAll();
11354                 }
11355             }
11356         };
11357
11358         try {
11359             who.linkToDeath(death, 0);
11360         } catch (RemoteException e) {
11361             Slog.w(TAG, "hang: given caller IBinder is already dead.");
11362             return;
11363         }
11364
11365         synchronized (this) {
11366             Watchdog.getInstance().setAllowRestart(allowRestart);
11367             Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
11368             synchronized (death) {
11369                 while (who.isBinderAlive()) {
11370                     try {
11371                         death.wait();
11372                     } catch (InterruptedException e) {
11373                     }
11374                 }
11375             }
11376             Watchdog.getInstance().setAllowRestart(true);
11377         }
11378     }
11379
11380     @Override
11381     public void restart() {
11382         if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
11383                 != PackageManager.PERMISSION_GRANTED) {
11384             throw new SecurityException("Requires permission "
11385                     + android.Manifest.permission.SET_ACTIVITY_WATCHER);
11386         }
11387
11388         Log.i(TAG, "Sending shutdown broadcast...");
11389
11390         BroadcastReceiver br = new BroadcastReceiver() {
11391             @Override public void onReceive(Context context, Intent intent) {
11392                 // Now the broadcast is done, finish up the low-level shutdown.
11393                 Log.i(TAG, "Shutting down activity manager...");
11394                 shutdown(10000);
11395                 Log.i(TAG, "Shutdown complete, restarting!");
11396                 Process.killProcess(Process.myPid());
11397                 System.exit(10);
11398             }
11399         };
11400
11401         // First send the high-level shut down broadcast.
11402         Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
11403         intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
11404         intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
11405         /* For now we are not doing a clean shutdown, because things seem to get unhappy.
11406         mContext.sendOrderedBroadcastAsUser(intent,
11407                 UserHandle.ALL, null, br, mHandler, 0, null, null);
11408         */
11409         br.onReceive(mContext, intent);
11410     }
11411
11412     private long getLowRamTimeSinceIdle(long now) {
11413         return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
11414     }
11415
11416     @Override
11417     public void performIdleMaintenance() {
11418         if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
11419                 != PackageManager.PERMISSION_GRANTED) {
11420             throw new SecurityException("Requires permission "
11421                     + android.Manifest.permission.SET_ACTIVITY_WATCHER);
11422         }
11423
11424         synchronized (this) {
11425             final long now = SystemClock.uptimeMillis();
11426             final long timeSinceLastIdle = now - mLastIdleTime;
11427             final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
11428             mLastIdleTime = now;
11429             mLowRamTimeSinceLastIdle = 0;
11430             if (mLowRamStartTime != 0) {
11431                 mLowRamStartTime = now;
11432             }
11433
11434             StringBuilder sb = new StringBuilder(128);
11435             sb.append("Idle maintenance over ");
11436             TimeUtils.formatDuration(timeSinceLastIdle, sb);
11437             sb.append(" low RAM for ");
11438             TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
11439             Slog.i(TAG, sb.toString());
11440
11441             // If at least 1/3 of our time since the last idle period has been spent
11442             // with RAM low, then we want to kill processes.
11443             boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
11444
11445             for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
11446                 ProcessRecord proc = mLruProcesses.get(i);
11447                 if (proc.notCachedSinceIdle) {
11448                     if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
11449                             && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
11450                             && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
11451                         if (doKilling && proc.initialIdlePss != 0
11452                                 && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
11453                             sb = new StringBuilder(128);
11454                             sb.append("Kill");
11455                             sb.append(proc.processName);
11456                             sb.append(" in idle maint: pss=");
11457                             sb.append(proc.lastPss);
11458                             sb.append(", initialPss=");
11459                             sb.append(proc.initialIdlePss);
11460                             sb.append(", period=");
11461                             TimeUtils.formatDuration(timeSinceLastIdle, sb);
11462                             sb.append(", lowRamPeriod=");
11463                             TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
11464                             Slog.wtfQuiet(TAG, sb.toString());
11465                             proc.kill("idle maint (pss " + proc.lastPss
11466                                     + " from " + proc.initialIdlePss + ")", true);
11467                         }
11468                     }
11469                 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
11470                     proc.notCachedSinceIdle = true;
11471                     proc.initialIdlePss = 0;
11472                     proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
11473                             mTestPssMode, isSleeping(), now);
11474                 }
11475             }
11476
11477             mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
11478             mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
11479         }
11480     }
11481
11482     private void retrieveSettings() {
11483         final ContentResolver resolver = mContext.getContentResolver();
11484         String debugApp = Settings.Global.getString(
11485             resolver, Settings.Global.DEBUG_APP);
11486         boolean waitForDebugger = Settings.Global.getInt(
11487             resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
11488         boolean alwaysFinishActivities = Settings.Global.getInt(
11489             resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
11490         boolean forceRtl = Settings.Global.getInt(
11491                 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
11492         // Transfer any global setting for forcing RTL layout, into a System Property
11493         SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
11494
11495         Configuration configuration = new Configuration();
11496         Settings.System.getConfiguration(resolver, configuration);
11497         if (forceRtl) {
11498             // This will take care of setting the correct layout direction flags
11499             configuration.setLayoutDirection(configuration.locale);
11500         }
11501
11502         synchronized (this) {
11503             mDebugApp = mOrigDebugApp = debugApp;
11504             mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
11505             mAlwaysFinishActivities = alwaysFinishActivities;
11506             // This happens before any activities are started, so we can
11507             // change mConfiguration in-place.
11508             updateConfigurationLocked(configuration, null, false, true);
11509             if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
11510                     "Initial config: " + mConfiguration);
11511         }
11512     }
11513
11514     /** Loads resources after the current configuration has been set. */
11515     private void loadResourcesOnSystemReady() {
11516         final Resources res = mContext.getResources();
11517         mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
11518         mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
11519         mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
11520     }
11521
11522     public boolean testIsSystemReady() {
11523         // no need to synchronize(this) just to read & return the value
11524         return mSystemReady;
11525     }
11526
11527     private static File getCalledPreBootReceiversFile() {
11528         File dataDir = Environment.getDataDirectory();
11529         File systemDir = new File(dataDir, "system");
11530         File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
11531         return fname;
11532     }
11533
11534     private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
11535         ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
11536         File file = getCalledPreBootReceiversFile();
11537         FileInputStream fis = null;
11538         try {
11539             fis = new FileInputStream(file);
11540             DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
11541             int fvers = dis.readInt();
11542             if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
11543                 String vers = dis.readUTF();
11544                 String codename = dis.readUTF();
11545                 String build = dis.readUTF();
11546                 if (android.os.Build.VERSION.RELEASE.equals(vers)
11547                         && android.os.Build.VERSION.CODENAME.equals(codename)
11548                         && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
11549                     int num = dis.readInt();
11550                     while (num > 0) {
11551                         num--;
11552                         String pkg = dis.readUTF();
11553                         String cls = dis.readUTF();
11554                         lastDoneReceivers.add(new ComponentName(pkg, cls));
11555                     }
11556                 }
11557             }
11558         } catch (FileNotFoundException e) {
11559         } catch (IOException e) {
11560             Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
11561         } finally {
11562             if (fis != null) {
11563                 try {
11564                     fis.close();
11565                 } catch (IOException e) {
11566                 }
11567             }
11568         }
11569         return lastDoneReceivers;
11570     }
11571
11572     private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
11573         File file = getCalledPreBootReceiversFile();
11574         FileOutputStream fos = null;
11575         DataOutputStream dos = null;
11576         try {
11577             fos = new FileOutputStream(file);
11578             dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
11579             dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
11580             dos.writeUTF(android.os.Build.VERSION.RELEASE);
11581             dos.writeUTF(android.os.Build.VERSION.CODENAME);
11582             dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
11583             dos.writeInt(list.size());
11584             for (int i=0; i<list.size(); i++) {
11585                 dos.writeUTF(list.get(i).getPackageName());
11586                 dos.writeUTF(list.get(i).getClassName());
11587             }
11588         } catch (IOException e) {
11589             Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
11590             file.delete();
11591         } finally {
11592             FileUtils.sync(fos);
11593             if (dos != null) {
11594                 try {
11595                     dos.close();
11596                 } catch (IOException e) {
11597                     // TODO Auto-generated catch block
11598                     e.printStackTrace();
11599                 }
11600             }
11601         }
11602     }
11603
11604     final class PreBootContinuation extends IIntentReceiver.Stub {
11605         final Intent intent;
11606         final Runnable onFinishCallback;
11607         final ArrayList<ComponentName> doneReceivers;
11608         final List<ResolveInfo> ris;
11609         final int[] users;
11610         int lastRi = -1;
11611         int curRi = 0;
11612         int curUser = 0;
11613
11614         PreBootContinuation(Intent _intent, Runnable _onFinishCallback,
11615                 ArrayList<ComponentName> _doneReceivers, List<ResolveInfo> _ris, int[] _users) {
11616             intent = _intent;
11617             onFinishCallback = _onFinishCallback;
11618             doneReceivers = _doneReceivers;
11619             ris = _ris;
11620             users = _users;
11621         }
11622
11623         void go() {
11624             if (lastRi != curRi) {
11625                 ActivityInfo ai = ris.get(curRi).activityInfo;
11626                 ComponentName comp = new ComponentName(ai.packageName, ai.name);
11627                 intent.setComponent(comp);
11628                 doneReceivers.add(comp);
11629                 lastRi = curRi;
11630                 CharSequence label = ai.loadLabel(mContext.getPackageManager());
11631                 showBootMessage(mContext.getString(R.string.android_preparing_apk, label), false);
11632             }
11633             Slog.i(TAG, "Pre-boot of " + intent.getComponent().toShortString()
11634                     + " for user " + users[curUser]);
11635             EventLogTags.writeAmPreBoot(users[curUser], intent.getComponent().getPackageName());
11636             broadcastIntentLocked(null, null, intent, null, this,
11637                     0, null, null, null, AppOpsManager.OP_NONE,
11638                     null, true, false, MY_PID, Process.SYSTEM_UID, users[curUser]);
11639         }
11640
11641         public void performReceive(Intent intent, int resultCode,
11642                 String data, Bundle extras, boolean ordered,
11643                 boolean sticky, int sendingUser) {
11644             curUser++;
11645             if (curUser >= users.length) {
11646                 curUser = 0;
11647                 curRi++;
11648                 if (curRi >= ris.size()) {
11649                     // All done sending broadcasts!
11650                     if (onFinishCallback != null) {
11651                         // The raw IIntentReceiver interface is called
11652                         // with the AM lock held, so redispatch to
11653                         // execute our code without the lock.
11654                         mHandler.post(onFinishCallback);
11655                     }
11656                     return;
11657                 }
11658             }
11659             go();
11660         }
11661     }
11662
11663     private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
11664             ArrayList<ComponentName> doneReceivers, int userId) {
11665         Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
11666         List<ResolveInfo> ris = null;
11667         try {
11668             ris = AppGlobals.getPackageManager().queryIntentReceivers(
11669                     intent, null, 0, userId);
11670         } catch (RemoteException e) {
11671         }
11672         if (ris == null) {
11673             return false;
11674         }
11675         for (int i=ris.size()-1; i>=0; i--) {
11676             if ((ris.get(i).activityInfo.applicationInfo.flags
11677                     &ApplicationInfo.FLAG_SYSTEM) == 0) {
11678                 ris.remove(i);
11679             }
11680         }
11681         intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
11682
11683         // For User 0, load the version number. When delivering to a new user, deliver
11684         // to all receivers.
11685         if (userId == UserHandle.USER_OWNER) {
11686             ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
11687             for (int i=0; i<ris.size(); i++) {
11688                 ActivityInfo ai = ris.get(i).activityInfo;
11689                 ComponentName comp = new ComponentName(ai.packageName, ai.name);
11690                 if (lastDoneReceivers.contains(comp)) {
11691                     // We already did the pre boot receiver for this app with the current
11692                     // platform version, so don't do it again...
11693                     ris.remove(i);
11694                     i--;
11695                     // ...however, do keep it as one that has been done, so we don't
11696                     // forget about it when rewriting the file of last done receivers.
11697                     doneReceivers.add(comp);
11698                 }
11699             }
11700         }
11701
11702         if (ris.size() <= 0) {
11703             return false;
11704         }
11705
11706         // If primary user, send broadcast to all available users, else just to userId
11707         final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
11708                 : new int[] { userId };
11709         if (users.length <= 0) {
11710             return false;
11711         }
11712
11713         PreBootContinuation cont = new PreBootContinuation(intent, onFinishCallback, doneReceivers,
11714                 ris, users);
11715         cont.go();
11716         return true;
11717     }
11718
11719     public void systemReady(final Runnable goingCallback) {
11720         synchronized(this) {
11721             if (mSystemReady) {
11722                 // If we're done calling all the receivers, run the next "boot phase" passed in
11723                 // by the SystemServer
11724                 if (goingCallback != null) {
11725                     goingCallback.run();
11726                 }
11727                 return;
11728             }
11729
11730             mLocalDeviceIdleController
11731                     = LocalServices.getService(DeviceIdleController.LocalService.class);
11732
11733             // Make sure we have the current profile info, since it is needed for
11734             // security checks.
11735             updateCurrentProfileIdsLocked();
11736
11737             mRecentTasks.clear();
11738             mRecentTasks.addAll(mTaskPersister.restoreTasksLocked());
11739             mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
11740             mTaskPersister.startPersisting();
11741
11742             // Check to see if there are any update receivers to run.
11743             if (!mDidUpdate) {
11744                 if (mWaitingUpdate) {
11745                     return;
11746                 }
11747                 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
11748                 mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
11749                     public void run() {
11750                         synchronized (ActivityManagerService.this) {
11751                             mDidUpdate = true;
11752                         }
11753                         showBootMessage(mContext.getText(
11754                                 R.string.android_upgrading_complete),
11755                                 false);
11756                         writeLastDonePreBootReceivers(doneReceivers);
11757                         systemReady(goingCallback);
11758                     }
11759                 }, doneReceivers, UserHandle.USER_OWNER);
11760
11761                 if (mWaitingUpdate) {
11762                     return;
11763                 }
11764                 mDidUpdate = true;
11765             }
11766
11767             mAppOpsService.systemReady();
11768             mSystemReady = true;
11769         }
11770
11771         ArrayList<ProcessRecord> procsToKill = null;
11772         synchronized(mPidsSelfLocked) {
11773             for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
11774                 ProcessRecord proc = mPidsSelfLocked.valueAt(i);
11775                 if (!isAllowedWhileBooting(proc.info)){
11776                     if (procsToKill == null) {
11777                         procsToKill = new ArrayList<ProcessRecord>();
11778                     }
11779                     procsToKill.add(proc);
11780                 }
11781             }
11782         }
11783
11784         synchronized(this) {
11785             if (procsToKill != null) {
11786                 for (int i=procsToKill.size()-1; i>=0; i--) {
11787                     ProcessRecord proc = procsToKill.get(i);
11788                     Slog.i(TAG, "Removing system update proc: " + proc);
11789                     removeProcessLocked(proc, true, false, "system update done");
11790                 }
11791             }
11792
11793             // Now that we have cleaned up any update processes, we
11794             // are ready to start launching real processes and know that
11795             // we won't trample on them any more.
11796             mProcessesReady = true;
11797         }
11798
11799         Slog.i(TAG, "System now ready");
11800         EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
11801             SystemClock.uptimeMillis());
11802
11803         synchronized(this) {
11804             // Make sure we have no pre-ready processes sitting around.
11805
11806             if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11807                 ResolveInfo ri = mContext.getPackageManager()
11808                         .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
11809                                 STOCK_PM_FLAGS);
11810                 CharSequence errorMsg = null;
11811                 if (ri != null) {
11812                     ActivityInfo ai = ri.activityInfo;
11813                     ApplicationInfo app = ai.applicationInfo;
11814                     if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
11815                         mTopAction = Intent.ACTION_FACTORY_TEST;
11816                         mTopData = null;
11817                         mTopComponent = new ComponentName(app.packageName,
11818                                 ai.name);
11819                     } else {
11820                         errorMsg = mContext.getResources().getText(
11821                                 com.android.internal.R.string.factorytest_not_system);
11822                     }
11823                 } else {
11824                     errorMsg = mContext.getResources().getText(
11825                             com.android.internal.R.string.factorytest_no_action);
11826                 }
11827                 if (errorMsg != null) {
11828                     mTopAction = null;
11829                     mTopData = null;
11830                     mTopComponent = null;
11831                     Message msg = Message.obtain();
11832                     msg.what = SHOW_FACTORY_ERROR_MSG;
11833                     msg.getData().putCharSequence("msg", errorMsg);
11834                     mUiHandler.sendMessage(msg);
11835                 }
11836             }
11837         }
11838
11839         retrieveSettings();
11840         loadResourcesOnSystemReady();
11841
11842         synchronized (this) {
11843             readGrantedUriPermissionsLocked();
11844         }
11845
11846         if (goingCallback != null) goingCallback.run();
11847
11848         mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
11849                 Integer.toString(mCurrentUserId), mCurrentUserId);
11850         mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
11851                 Integer.toString(mCurrentUserId), mCurrentUserId);
11852         mSystemServiceManager.startUser(mCurrentUserId);
11853
11854         synchronized (this) {
11855             if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11856                 try {
11857                     List apps = AppGlobals.getPackageManager().
11858                         getPersistentApplications(STOCK_PM_FLAGS);
11859                     if (apps != null) {
11860                         int N = apps.size();
11861                         int i;
11862                         for (i=0; i<N; i++) {
11863                             ApplicationInfo info
11864                                 = (ApplicationInfo)apps.get(i);
11865                             if (info != null &&
11866                                     !info.packageName.equals("android")) {
11867                                 addAppLocked(info, false, null /* ABI override */);
11868                             }
11869                         }
11870                     }
11871                 } catch (RemoteException ex) {
11872                     // pm is in same process, this will never happen.
11873                 }
11874             }
11875
11876             // Start up initial activity.
11877             mBooting = true;
11878             startHomeActivityLocked(mCurrentUserId, "systemReady");
11879
11880             try {
11881                 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
11882                     Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
11883                             + " data partition or your device will be unstable.");
11884                     mUiHandler.obtainMessage(SHOW_UID_ERROR_MSG).sendToTarget();
11885                 }
11886             } catch (RemoteException e) {
11887             }
11888
11889             if (!Build.isBuildConsistent()) {
11890                 Slog.e(TAG, "Build fingerprint is not consistent, warning user");
11891                 mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_MSG).sendToTarget();
11892             }
11893
11894             long ident = Binder.clearCallingIdentity();
11895             try {
11896                 Intent intent = new Intent(Intent.ACTION_USER_STARTED);
11897                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
11898                         | Intent.FLAG_RECEIVER_FOREGROUND);
11899                 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11900                 broadcastIntentLocked(null, null, intent,
11901                         null, null, 0, null, null, null, AppOpsManager.OP_NONE,
11902                         null, false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
11903                 intent = new Intent(Intent.ACTION_USER_STARTING);
11904                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11905                 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11906                 broadcastIntentLocked(null, null, intent,
11907                         null, new IIntentReceiver.Stub() {
11908                             @Override
11909                             public void performReceive(Intent intent, int resultCode, String data,
11910                                     Bundle extras, boolean ordered, boolean sticky, int sendingUser)
11911                                     throws RemoteException {
11912                             }
11913                         }, 0, null, null,
11914                         new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
11915                         null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
11916             } catch (Throwable t) {
11917                 Slog.wtf(TAG, "Failed sending first user broadcasts", t);
11918             } finally {
11919                 Binder.restoreCallingIdentity(ident);
11920             }
11921             mStackSupervisor.resumeTopActivitiesLocked();
11922             sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
11923         }
11924     }
11925
11926     private boolean makeAppCrashingLocked(ProcessRecord app,
11927             String shortMsg, String longMsg, String stackTrace) {
11928         app.crashing = true;
11929         app.crashingReport = generateProcessError(app,
11930                 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
11931         startAppProblemLocked(app);
11932         app.stopFreezingAllLocked();
11933         return handleAppCrashLocked(app, "force-crash" /*reason*/, shortMsg, longMsg, stackTrace);
11934     }
11935
11936     private void makeAppNotRespondingLocked(ProcessRecord app,
11937             String activity, String shortMsg, String longMsg) {
11938         app.notResponding = true;
11939         app.notRespondingReport = generateProcessError(app,
11940                 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
11941                 activity, shortMsg, longMsg, null);
11942         startAppProblemLocked(app);
11943         app.stopFreezingAllLocked();
11944     }
11945
11946     /**
11947      * Generate a process error record, suitable for attachment to a ProcessRecord.
11948      *
11949      * @param app The ProcessRecord in which the error occurred.
11950      * @param condition Crashing, Application Not Responding, etc.  Values are defined in
11951      *                      ActivityManager.AppErrorStateInfo
11952      * @param activity The activity associated with the crash, if known.
11953      * @param shortMsg Short message describing the crash.
11954      * @param longMsg Long message describing the crash.
11955      * @param stackTrace Full crash stack trace, may be null.
11956      *
11957      * @return Returns a fully-formed AppErrorStateInfo record.
11958      */
11959     private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
11960             int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
11961         ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
11962
11963         report.condition = condition;
11964         report.processName = app.processName;
11965         report.pid = app.pid;
11966         report.uid = app.info.uid;
11967         report.tag = activity;
11968         report.shortMsg = shortMsg;
11969         report.longMsg = longMsg;
11970         report.stackTrace = stackTrace;
11971
11972         return report;
11973     }
11974
11975     void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
11976         synchronized (this) {
11977             app.crashing = false;
11978             app.crashingReport = null;
11979             app.notResponding = false;
11980             app.notRespondingReport = null;
11981             if (app.anrDialog == fromDialog) {
11982                 app.anrDialog = null;
11983             }
11984             if (app.waitDialog == fromDialog) {
11985                 app.waitDialog = null;
11986             }
11987             if (app.pid > 0 && app.pid != MY_PID) {
11988                 handleAppCrashLocked(app, "user-terminated" /*reason*/,
11989                         null /*shortMsg*/, null /*longMsg*/, null /*stackTrace*/);
11990                 app.kill("user request after error", true);
11991             }
11992         }
11993     }
11994
11995     private boolean handleAppCrashLocked(ProcessRecord app, String reason,
11996             String shortMsg, String longMsg, String stackTrace) {
11997         long now = SystemClock.uptimeMillis();
11998
11999         Long crashTime;
12000         if (!app.isolated) {
12001             crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
12002         } else {
12003             crashTime = null;
12004         }
12005         if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
12006             // This process loses!
12007             Slog.w(TAG, "Process " + app.info.processName
12008                     + " has crashed too many times: killing!");
12009             EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
12010                     app.userId, app.info.processName, app.uid);
12011             mStackSupervisor.handleAppCrashLocked(app);
12012             if (!app.persistent) {
12013                 // We don't want to start this process again until the user
12014                 // explicitly does so...  but for persistent process, we really
12015                 // need to keep it running.  If a persistent process is actually
12016                 // repeatedly crashing, then badness for everyone.
12017                 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
12018                         app.info.processName);
12019                 if (!app.isolated) {
12020                     // XXX We don't have a way to mark isolated processes
12021                     // as bad, since they don't have a peristent identity.
12022                     mBadProcesses.put(app.info.processName, app.uid,
12023                             new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
12024                     mProcessCrashTimes.remove(app.info.processName, app.uid);
12025                 }
12026                 app.bad = true;
12027                 app.removed = true;
12028                 // Don't let services in this process be restarted and potentially
12029                 // annoy the user repeatedly.  Unless it is persistent, since those
12030                 // processes run critical code.
12031                 removeProcessLocked(app, false, false, "crash");
12032                 mStackSupervisor.resumeTopActivitiesLocked();
12033                 return false;
12034             }
12035             mStackSupervisor.resumeTopActivitiesLocked();
12036         } else {
12037             mStackSupervisor.finishTopRunningActivityLocked(app, reason);
12038         }
12039
12040         // Bump up the crash count of any services currently running in the proc.
12041         for (int i=app.services.size()-1; i>=0; i--) {
12042             // Any services running in the application need to be placed
12043             // back in the pending list.
12044             ServiceRecord sr = app.services.valueAt(i);
12045             sr.crashCount++;
12046         }
12047
12048         // If the crashing process is what we consider to be the "home process" and it has been
12049         // replaced by a third-party app, clear the package preferred activities from packages
12050         // with a home activity running in the process to prevent a repeatedly crashing app
12051         // from blocking the user to manually clear the list.
12052         final ArrayList<ActivityRecord> activities = app.activities;
12053         if (app == mHomeProcess && activities.size() > 0
12054                     && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
12055             for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
12056                 final ActivityRecord r = activities.get(activityNdx);
12057                 if (r.isHomeActivity()) {
12058                     Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
12059                     try {
12060                         ActivityThread.getPackageManager()
12061                                 .clearPackagePreferredActivities(r.packageName);
12062                     } catch (RemoteException c) {
12063                         // pm is in same process, this will never happen.
12064                     }
12065                 }
12066             }
12067         }
12068
12069         if (!app.isolated) {
12070             // XXX Can't keep track of crash times for isolated processes,
12071             // because they don't have a perisistent identity.
12072             mProcessCrashTimes.put(app.info.processName, app.uid, now);
12073         }
12074
12075         if (app.crashHandler != null) mHandler.post(app.crashHandler);
12076         return true;
12077     }
12078
12079     void startAppProblemLocked(ProcessRecord app) {
12080         // If this app is not running under the current user, then we
12081         // can't give it a report button because that would require
12082         // launching the report UI under a different user.
12083         app.errorReportReceiver = null;
12084
12085         for (int userId : mCurrentProfileIds) {
12086             if (app.userId == userId) {
12087                 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
12088                         mContext, app.info.packageName, app.info.flags);
12089             }
12090         }
12091         skipCurrentReceiverLocked(app);
12092     }
12093
12094     void skipCurrentReceiverLocked(ProcessRecord app) {
12095         for (BroadcastQueue queue : mBroadcastQueues) {
12096             queue.skipCurrentReceiverLocked(app);
12097         }
12098     }
12099
12100     /**
12101      * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
12102      * The application process will exit immediately after this call returns.
12103      * @param app object of the crashing app, null for the system server
12104      * @param crashInfo describing the exception
12105      */
12106     public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
12107         ProcessRecord r = findAppProcess(app, "Crash");
12108         final String processName = app == null ? "system_server"
12109                 : (r == null ? "unknown" : r.processName);
12110
12111         handleApplicationCrashInner("crash", r, processName, crashInfo);
12112     }
12113
12114     /* Native crash reporting uses this inner version because it needs to be somewhat
12115      * decoupled from the AM-managed cleanup lifecycle
12116      */
12117     void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
12118             ApplicationErrorReport.CrashInfo crashInfo) {
12119         EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
12120                 UserHandle.getUserId(Binder.getCallingUid()), processName,
12121                 r == null ? -1 : r.info.flags,
12122                 crashInfo.exceptionClassName,
12123                 crashInfo.exceptionMessage,
12124                 crashInfo.throwFileName,
12125                 crashInfo.throwLineNumber);
12126
12127         addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
12128
12129         crashApplication(r, crashInfo);
12130     }
12131
12132     public void handleApplicationStrictModeViolation(
12133             IBinder app,
12134             int violationMask,
12135             StrictMode.ViolationInfo info) {
12136         ProcessRecord r = findAppProcess(app, "StrictMode");
12137         if (r == null) {
12138             return;
12139         }
12140
12141         if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
12142             Integer stackFingerprint = info.hashCode();
12143             boolean logIt = true;
12144             synchronized (mAlreadyLoggedViolatedStacks) {
12145                 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
12146                     logIt = false;
12147                     // TODO: sub-sample into EventLog for these, with
12148                     // the info.durationMillis?  Then we'd get
12149                     // the relative pain numbers, without logging all
12150                     // the stack traces repeatedly.  We'd want to do
12151                     // likewise in the client code, which also does
12152                     // dup suppression, before the Binder call.
12153                 } else {
12154                     if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
12155                         mAlreadyLoggedViolatedStacks.clear();
12156                     }
12157                     mAlreadyLoggedViolatedStacks.add(stackFingerprint);
12158                 }
12159             }
12160             if (logIt) {
12161                 logStrictModeViolationToDropBox(r, info);
12162             }
12163         }
12164
12165         if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
12166             AppErrorResult result = new AppErrorResult();
12167             synchronized (this) {
12168                 final long origId = Binder.clearCallingIdentity();
12169
12170                 Message msg = Message.obtain();
12171                 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
12172                 HashMap<String, Object> data = new HashMap<String, Object>();
12173                 data.put("result", result);
12174                 data.put("app", r);
12175                 data.put("violationMask", violationMask);
12176                 data.put("info", info);
12177                 msg.obj = data;
12178                 mUiHandler.sendMessage(msg);
12179
12180                 Binder.restoreCallingIdentity(origId);
12181             }
12182             int res = result.get();
12183             Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
12184         }
12185     }
12186
12187     // Depending on the policy in effect, there could be a bunch of
12188     // these in quick succession so we try to batch these together to
12189     // minimize disk writes, number of dropbox entries, and maximize
12190     // compression, by having more fewer, larger records.
12191     private void logStrictModeViolationToDropBox(
12192             ProcessRecord process,
12193             StrictMode.ViolationInfo info) {
12194         if (info == null) {
12195             return;
12196         }
12197         final boolean isSystemApp = process == null ||
12198                 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
12199                                        ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
12200         final String processName = process == null ? "unknown" : process.processName;
12201         final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
12202         final DropBoxManager dbox = (DropBoxManager)
12203                 mContext.getSystemService(Context.DROPBOX_SERVICE);
12204
12205         // Exit early if the dropbox isn't configured to accept this report type.
12206         if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
12207
12208         boolean bufferWasEmpty;
12209         boolean needsFlush;
12210         final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
12211         synchronized (sb) {
12212             bufferWasEmpty = sb.length() == 0;
12213             appendDropBoxProcessHeaders(process, processName, sb);
12214             sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
12215             sb.append("System-App: ").append(isSystemApp).append("\n");
12216             sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
12217             if (info.violationNumThisLoop != 0) {
12218                 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
12219             }
12220             if (info.numAnimationsRunning != 0) {
12221                 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
12222             }
12223             if (info.broadcastIntentAction != null) {
12224                 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
12225             }
12226             if (info.durationMillis != -1) {
12227                 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
12228             }
12229             if (info.numInstances != -1) {
12230                 sb.append("Instance-Count: ").append(info.numInstances).append("\n");
12231             }
12232             if (info.tags != null) {
12233                 for (String tag : info.tags) {
12234                     sb.append("Span-Tag: ").append(tag).append("\n");
12235                 }
12236             }
12237             sb.append("\n");
12238             if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
12239                 sb.append(info.crashInfo.stackTrace);
12240                 sb.append("\n");
12241             }
12242             if (info.message != null) {
12243                 sb.append(info.message);
12244                 sb.append("\n");
12245             }
12246
12247             // Only buffer up to ~64k.  Various logging bits truncate
12248             // things at 128k.
12249             needsFlush = (sb.length() > 64 * 1024);
12250         }
12251
12252         // Flush immediately if the buffer's grown too large, or this
12253         // is a non-system app.  Non-system apps are isolated with a
12254         // different tag & policy and not batched.
12255         //
12256         // Batching is useful during internal testing with
12257         // StrictMode settings turned up high.  Without batching,
12258         // thousands of separate files could be created on boot.
12259         if (!isSystemApp || needsFlush) {
12260             new Thread("Error dump: " + dropboxTag) {
12261                 @Override
12262                 public void run() {
12263                     String report;
12264                     synchronized (sb) {
12265                         report = sb.toString();
12266                         sb.delete(0, sb.length());
12267                         sb.trimToSize();
12268                     }
12269                     if (report.length() != 0) {
12270                         dbox.addText(dropboxTag, report);
12271                     }
12272                 }
12273             }.start();
12274             return;
12275         }
12276
12277         // System app batching:
12278         if (!bufferWasEmpty) {
12279             // An existing dropbox-writing thread is outstanding, so
12280             // we don't need to start it up.  The existing thread will
12281             // catch the buffer appends we just did.
12282             return;
12283         }
12284
12285         // Worker thread to both batch writes and to avoid blocking the caller on I/O.
12286         // (After this point, we shouldn't access AMS internal data structures.)
12287         new Thread("Error dump: " + dropboxTag) {
12288             @Override
12289             public void run() {
12290                 // 5 second sleep to let stacks arrive and be batched together
12291                 try {
12292                     Thread.sleep(5000);  // 5 seconds
12293                 } catch (InterruptedException e) {}
12294
12295                 String errorReport;
12296                 synchronized (mStrictModeBuffer) {
12297                     errorReport = mStrictModeBuffer.toString();
12298                     if (errorReport.length() == 0) {
12299                         return;
12300                     }
12301                     mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
12302                     mStrictModeBuffer.trimToSize();
12303                 }
12304                 dbox.addText(dropboxTag, errorReport);
12305             }
12306         }.start();
12307     }
12308
12309     /**
12310      * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
12311      * @param app object of the crashing app, null for the system server
12312      * @param tag reported by the caller
12313      * @param system whether this wtf is coming from the system
12314      * @param crashInfo describing the context of the error
12315      * @return true if the process should exit immediately (WTF is fatal)
12316      */
12317     public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
12318             final ApplicationErrorReport.CrashInfo crashInfo) {
12319         final int callingUid = Binder.getCallingUid();
12320         final int callingPid = Binder.getCallingPid();
12321
12322         if (system) {
12323             // If this is coming from the system, we could very well have low-level
12324             // system locks held, so we want to do this all asynchronously.  And we
12325             // never want this to become fatal, so there is that too.
12326             mHandler.post(new Runnable() {
12327                 @Override public void run() {
12328                     handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
12329                 }
12330             });
12331             return false;
12332         }
12333
12334         final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
12335                 crashInfo);
12336
12337         if (r != null && r.pid != Process.myPid() &&
12338                 Settings.Global.getInt(mContext.getContentResolver(),
12339                         Settings.Global.WTF_IS_FATAL, 0) != 0) {
12340             crashApplication(r, crashInfo);
12341             return true;
12342         } else {
12343             return false;
12344         }
12345     }
12346
12347     ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
12348             final ApplicationErrorReport.CrashInfo crashInfo) {
12349         final ProcessRecord r = findAppProcess(app, "WTF");
12350         final String processName = app == null ? "system_server"
12351                 : (r == null ? "unknown" : r.processName);
12352
12353         EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
12354                 processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
12355
12356         addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
12357
12358         return r;
12359     }
12360
12361     /**
12362      * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
12363      * @return the corresponding {@link ProcessRecord} object, or null if none could be found
12364      */
12365     private ProcessRecord findAppProcess(IBinder app, String reason) {
12366         if (app == null) {
12367             return null;
12368         }
12369
12370         synchronized (this) {
12371             final int NP = mProcessNames.getMap().size();
12372             for (int ip=0; ip<NP; ip++) {
12373                 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
12374                 final int NA = apps.size();
12375                 for (int ia=0; ia<NA; ia++) {
12376                     ProcessRecord p = apps.valueAt(ia);
12377                     if (p.thread != null && p.thread.asBinder() == app) {
12378                         return p;
12379                     }
12380                 }
12381             }
12382
12383             Slog.w(TAG, "Can't find mystery application for " + reason
12384                     + " from pid=" + Binder.getCallingPid()
12385                     + " uid=" + Binder.getCallingUid() + ": " + app);
12386             return null;
12387         }
12388     }
12389
12390     /**
12391      * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
12392      * to append various headers to the dropbox log text.
12393      */
12394     private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
12395             StringBuilder sb) {
12396         // Watchdog thread ends up invoking this function (with
12397         // a null ProcessRecord) to add the stack file to dropbox.
12398         // Do not acquire a lock on this (am) in such cases, as it
12399         // could cause a potential deadlock, if and when watchdog
12400         // is invoked due to unavailability of lock on am and it
12401         // would prevent watchdog from killing system_server.
12402         if (process == null) {
12403             sb.append("Process: ").append(processName).append("\n");
12404             return;
12405         }
12406         // Note: ProcessRecord 'process' is guarded by the service
12407         // instance.  (notably process.pkgList, which could otherwise change
12408         // concurrently during execution of this method)
12409         synchronized (this) {
12410             sb.append("Process: ").append(processName).append("\n");
12411             int flags = process.info.flags;
12412             IPackageManager pm = AppGlobals.getPackageManager();
12413             sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
12414             for (int ip=0; ip<process.pkgList.size(); ip++) {
12415                 String pkg = process.pkgList.keyAt(ip);
12416                 sb.append("Package: ").append(pkg);
12417                 try {
12418                     PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
12419                     if (pi != null) {
12420                         sb.append(" v").append(pi.versionCode);
12421                         if (pi.versionName != null) {
12422                             sb.append(" (").append(pi.versionName).append(")");
12423                         }
12424                     }
12425                 } catch (RemoteException e) {
12426                     Slog.e(TAG, "Error getting package info: " + pkg, e);
12427                 }
12428                 sb.append("\n");
12429             }
12430         }
12431     }
12432
12433     private static String processClass(ProcessRecord process) {
12434         if (process == null || process.pid == MY_PID) {
12435             return "system_server";
12436         } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
12437             return "system_app";
12438         } else {
12439             return "data_app";
12440         }
12441     }
12442
12443     /**
12444      * Write a description of an error (crash, WTF, ANR) to the drop box.
12445      * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
12446      * @param process which caused the error, null means the system server
12447      * @param activity which triggered the error, null if unknown
12448      * @param parent activity related to the error, null if unknown
12449      * @param subject line related to the error, null if absent
12450      * @param report in long form describing the error, null if absent
12451      * @param logFile to include in the report, null if none
12452      * @param crashInfo giving an application stack trace, null if absent
12453      */
12454     public void addErrorToDropBox(String eventType,
12455             ProcessRecord process, String processName, ActivityRecord activity,
12456             ActivityRecord parent, String subject,
12457             final String report, final File logFile,
12458             final ApplicationErrorReport.CrashInfo crashInfo) {
12459         // NOTE -- this must never acquire the ActivityManagerService lock,
12460         // otherwise the watchdog may be prevented from resetting the system.
12461
12462         final String dropboxTag = processClass(process) + "_" + eventType;
12463         final DropBoxManager dbox = (DropBoxManager)
12464                 mContext.getSystemService(Context.DROPBOX_SERVICE);
12465
12466         // Exit early if the dropbox isn't configured to accept this report type.
12467         if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
12468
12469         final StringBuilder sb = new StringBuilder(1024);
12470         appendDropBoxProcessHeaders(process, processName, sb);
12471         if (activity != null) {
12472             sb.append("Activity: ").append(activity.shortComponentName).append("\n");
12473         }
12474         if (parent != null && parent.app != null && parent.app.pid != process.pid) {
12475             sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
12476         }
12477         if (parent != null && parent != activity) {
12478             sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
12479         }
12480         if (subject != null) {
12481             sb.append("Subject: ").append(subject).append("\n");
12482         }
12483         sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
12484         if (Debug.isDebuggerConnected()) {
12485             sb.append("Debugger: Connected\n");
12486         }
12487         sb.append("\n");
12488
12489         // Do the rest in a worker thread to avoid blocking the caller on I/O
12490         // (After this point, we shouldn't access AMS internal data structures.)
12491         Thread worker = new Thread("Error dump: " + dropboxTag) {
12492             @Override
12493             public void run() {
12494                 if (report != null) {
12495                     sb.append(report);
12496                 }
12497                 if (logFile != null) {
12498                     try {
12499                         sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
12500                                     "\n\n[[TRUNCATED]]"));
12501                     } catch (IOException e) {
12502                         Slog.e(TAG, "Error reading " + logFile, e);
12503                     }
12504                 }
12505                 if (crashInfo != null && crashInfo.stackTrace != null) {
12506                     sb.append(crashInfo.stackTrace);
12507                 }
12508
12509                 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
12510                 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
12511                 if (lines > 0) {
12512                     sb.append("\n");
12513
12514                     // Merge several logcat streams, and take the last N lines
12515                     InputStreamReader input = null;
12516                     try {
12517                         java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
12518                                 "-v", "time", "-b", "events", "-b", "system", "-b", "main",
12519                                 "-b", "crash",
12520                                 "-t", String.valueOf(lines)).redirectErrorStream(true).start();
12521
12522                         try { logcat.getOutputStream().close(); } catch (IOException e) {}
12523                         try { logcat.getErrorStream().close(); } catch (IOException e) {}
12524                         input = new InputStreamReader(logcat.getInputStream());
12525
12526                         int num;
12527                         char[] buf = new char[8192];
12528                         while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
12529                     } catch (IOException e) {
12530                         Slog.e(TAG, "Error running logcat", e);
12531                     } finally {
12532                         if (input != null) try { input.close(); } catch (IOException e) {}
12533                     }
12534                 }
12535
12536                 dbox.addText(dropboxTag, sb.toString());
12537             }
12538         };
12539
12540         if (process == null) {
12541             // If process is null, we are being called from some internal code
12542             // and may be about to die -- run this synchronously.
12543             worker.run();
12544         } else {
12545             worker.start();
12546         }
12547     }
12548
12549     /**
12550      * Bring up the "unexpected error" dialog box for a crashing app.
12551      * Deal with edge cases (intercepts from instrumented applications,
12552      * ActivityController, error intent receivers, that sort of thing).
12553      * @param r the application crashing
12554      * @param crashInfo describing the failure
12555      */
12556     private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
12557         long timeMillis = System.currentTimeMillis();
12558         String shortMsg = crashInfo.exceptionClassName;
12559         String longMsg = crashInfo.exceptionMessage;
12560         String stackTrace = crashInfo.stackTrace;
12561         if (shortMsg != null && longMsg != null) {
12562             longMsg = shortMsg + ": " + longMsg;
12563         } else if (shortMsg != null) {
12564             longMsg = shortMsg;
12565         }
12566
12567         AppErrorResult result = new AppErrorResult();
12568         synchronized (this) {
12569             if (mController != null) {
12570                 try {
12571                     String name = r != null ? r.processName : null;
12572                     int pid = r != null ? r.pid : Binder.getCallingPid();
12573                     int uid = r != null ? r.info.uid : Binder.getCallingUid();
12574                     if (!mController.appCrashed(name, pid,
12575                             shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
12576                         if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
12577                                 && "Native crash".equals(crashInfo.exceptionClassName)) {
12578                             Slog.w(TAG, "Skip killing native crashed app " + name
12579                                     + "(" + pid + ") during testing");
12580                         } else {
12581                             Slog.w(TAG, "Force-killing crashed app " + name
12582                                     + " at watcher's request");
12583                             if (r != null) {
12584                                 r.kill("crash", true);
12585                             } else {
12586                                 // Huh.
12587                                 Process.killProcess(pid);
12588                                 killProcessGroup(uid, pid);
12589                             }
12590                         }
12591                         return;
12592                     }
12593                 } catch (RemoteException e) {
12594                     mController = null;
12595                     Watchdog.getInstance().setActivityController(null);
12596                 }
12597             }
12598
12599             final long origId = Binder.clearCallingIdentity();
12600
12601             // If this process is running instrumentation, finish it.
12602             if (r != null && r.instrumentationClass != null) {
12603                 Slog.w(TAG, "Error in app " + r.processName
12604                       + " running instrumentation " + r.instrumentationClass + ":");
12605                 if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
12606                 if (longMsg != null) Slog.w(TAG, "  " + longMsg);
12607                 Bundle info = new Bundle();
12608                 info.putString("shortMsg", shortMsg);
12609                 info.putString("longMsg", longMsg);
12610                 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
12611                 Binder.restoreCallingIdentity(origId);
12612                 return;
12613             }
12614
12615             // Log crash in battery stats.
12616             if (r != null) {
12617                 mBatteryStatsService.noteProcessCrash(r.processName, r.uid);
12618             }
12619
12620             // If we can't identify the process or it's already exceeded its crash quota,
12621             // quit right away without showing a crash dialog.
12622             if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
12623                 Binder.restoreCallingIdentity(origId);
12624                 return;
12625             }
12626
12627             Message msg = Message.obtain();
12628             msg.what = SHOW_ERROR_MSG;
12629             HashMap data = new HashMap();
12630             data.put("result", result);
12631             data.put("app", r);
12632             msg.obj = data;
12633             mUiHandler.sendMessage(msg);
12634
12635             Binder.restoreCallingIdentity(origId);
12636         }
12637
12638         int res = result.get();
12639
12640         Intent appErrorIntent = null;
12641         synchronized (this) {
12642             if (r != null && !r.isolated) {
12643                 // XXX Can't keep track of crash time for isolated processes,
12644                 // since they don't have a persistent identity.
12645                 mProcessCrashTimes.put(r.info.processName, r.uid,
12646                         SystemClock.uptimeMillis());
12647             }
12648             if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
12649                 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
12650             }
12651         }
12652
12653         if (appErrorIntent != null) {
12654             try {
12655                 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
12656             } catch (ActivityNotFoundException e) {
12657                 Slog.w(TAG, "bug report receiver dissappeared", e);
12658             }
12659         }
12660     }
12661
12662     Intent createAppErrorIntentLocked(ProcessRecord r,
12663             long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12664         ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
12665         if (report == null) {
12666             return null;
12667         }
12668         Intent result = new Intent(Intent.ACTION_APP_ERROR);
12669         result.setComponent(r.errorReportReceiver);
12670         result.putExtra(Intent.EXTRA_BUG_REPORT, report);
12671         result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
12672         return result;
12673     }
12674
12675     private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
12676             long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12677         if (r.errorReportReceiver == null) {
12678             return null;
12679         }
12680
12681         if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
12682             return null;
12683         }
12684
12685         ApplicationErrorReport report = new ApplicationErrorReport();
12686         report.packageName = r.info.packageName;
12687         report.installerPackageName = r.errorReportReceiver.getPackageName();
12688         report.processName = r.processName;
12689         report.time = timeMillis;
12690         report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
12691
12692         if (r.crashing || r.forceCrashReport) {
12693             report.type = ApplicationErrorReport.TYPE_CRASH;
12694             report.crashInfo = crashInfo;
12695         } else if (r.notResponding) {
12696             report.type = ApplicationErrorReport.TYPE_ANR;
12697             report.anrInfo = new ApplicationErrorReport.AnrInfo();
12698
12699             report.anrInfo.activity = r.notRespondingReport.tag;
12700             report.anrInfo.cause = r.notRespondingReport.shortMsg;
12701             report.anrInfo.info = r.notRespondingReport.longMsg;
12702         }
12703
12704         return report;
12705     }
12706
12707     public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
12708         enforceNotIsolatedCaller("getProcessesInErrorState");
12709         // assume our apps are happy - lazy create the list
12710         List<ActivityManager.ProcessErrorStateInfo> errList = null;
12711
12712         final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12713                 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12714         int userId = UserHandle.getUserId(Binder.getCallingUid());
12715
12716         synchronized (this) {
12717
12718             // iterate across all processes
12719             for (int i=mLruProcesses.size()-1; i>=0; i--) {
12720                 ProcessRecord app = mLruProcesses.get(i);
12721                 if (!allUsers && app.userId != userId) {
12722                     continue;
12723                 }
12724                 if ((app.thread != null) && (app.crashing || app.notResponding)) {
12725                     // This one's in trouble, so we'll generate a report for it
12726                     // crashes are higher priority (in case there's a crash *and* an anr)
12727                     ActivityManager.ProcessErrorStateInfo report = null;
12728                     if (app.crashing) {
12729                         report = app.crashingReport;
12730                     } else if (app.notResponding) {
12731                         report = app.notRespondingReport;
12732                     }
12733
12734                     if (report != null) {
12735                         if (errList == null) {
12736                             errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
12737                         }
12738                         errList.add(report);
12739                     } else {
12740                         Slog.w(TAG, "Missing app error report, app = " + app.processName +
12741                                 " crashing = " + app.crashing +
12742                                 " notResponding = " + app.notResponding);
12743                     }
12744                 }
12745             }
12746         }
12747
12748         return errList;
12749     }
12750
12751     static int procStateToImportance(int procState, int memAdj,
12752             ActivityManager.RunningAppProcessInfo currApp) {
12753         int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
12754         if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
12755             currApp.lru = memAdj;
12756         } else {
12757             currApp.lru = 0;
12758         }
12759         return imp;
12760     }
12761
12762     private void fillInProcMemInfo(ProcessRecord app,
12763             ActivityManager.RunningAppProcessInfo outInfo) {
12764         outInfo.pid = app.pid;
12765         outInfo.uid = app.info.uid;
12766         if (mHeavyWeightProcess == app) {
12767             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
12768         }
12769         if (app.persistent) {
12770             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
12771         }
12772         if (app.activities.size() > 0) {
12773             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
12774         }
12775         outInfo.lastTrimLevel = app.trimMemoryLevel;
12776         int adj = app.curAdj;
12777         int procState = app.curProcState;
12778         outInfo.importance = procStateToImportance(procState, adj, outInfo);
12779         outInfo.importanceReasonCode = app.adjTypeCode;
12780         outInfo.processState = app.curProcState;
12781     }
12782
12783     public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
12784         enforceNotIsolatedCaller("getRunningAppProcesses");
12785
12786         final int callingUid = Binder.getCallingUid();
12787
12788         // Lazy instantiation of list
12789         List<ActivityManager.RunningAppProcessInfo> runList = null;
12790         final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12791                 callingUid) == PackageManager.PERMISSION_GRANTED;
12792         final int userId = UserHandle.getUserId(callingUid);
12793         final boolean allUids = isGetTasksAllowed(
12794                 "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
12795
12796         synchronized (this) {
12797             // Iterate across all processes
12798             for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
12799                 ProcessRecord app = mLruProcesses.get(i);
12800                 if ((!allUsers && app.userId != userId)
12801                         || (!allUids && app.uid != callingUid)) {
12802                     continue;
12803                 }
12804                 if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
12805                     // Generate process state info for running application
12806                     ActivityManager.RunningAppProcessInfo currApp =
12807                         new ActivityManager.RunningAppProcessInfo(app.processName,
12808                                 app.pid, app.getPackageList());
12809                     fillInProcMemInfo(app, currApp);
12810                     if (app.adjSource instanceof ProcessRecord) {
12811                         currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
12812                         currApp.importanceReasonImportance =
12813                                 ActivityManager.RunningAppProcessInfo.procStateToImportance(
12814                                         app.adjSourceProcState);
12815                     } else if (app.adjSource instanceof ActivityRecord) {
12816                         ActivityRecord r = (ActivityRecord)app.adjSource;
12817                         if (r.app != null) currApp.importanceReasonPid = r.app.pid;
12818                     }
12819                     if (app.adjTarget instanceof ComponentName) {
12820                         currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
12821                     }
12822                     //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
12823                     //        + " lru=" + currApp.lru);
12824                     if (runList == null) {
12825                         runList = new ArrayList<>();
12826                     }
12827                     runList.add(currApp);
12828                 }
12829             }
12830         }
12831         return runList;
12832     }
12833
12834     public List<ApplicationInfo> getRunningExternalApplications() {
12835         enforceNotIsolatedCaller("getRunningExternalApplications");
12836         List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
12837         List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
12838         if (runningApps != null && runningApps.size() > 0) {
12839             Set<String> extList = new HashSet<String>();
12840             for (ActivityManager.RunningAppProcessInfo app : runningApps) {
12841                 if (app.pkgList != null) {
12842                     for (String pkg : app.pkgList) {
12843                         extList.add(pkg);
12844                     }
12845                 }
12846             }
12847             IPackageManager pm = AppGlobals.getPackageManager();
12848             for (String pkg : extList) {
12849                 try {
12850                     ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
12851                     if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
12852                         retList.add(info);
12853                     }
12854                 } catch (RemoteException e) {
12855                 }
12856             }
12857         }
12858         return retList;
12859     }
12860
12861     @Override
12862     public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
12863         enforceNotIsolatedCaller("getMyMemoryState");
12864         synchronized (this) {
12865             ProcessRecord proc;
12866             synchronized (mPidsSelfLocked) {
12867                 proc = mPidsSelfLocked.get(Binder.getCallingPid());
12868             }
12869             fillInProcMemInfo(proc, outInfo);
12870         }
12871     }
12872
12873     @Override
12874     protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
12875         if (checkCallingPermission(android.Manifest.permission.DUMP)
12876                 != PackageManager.PERMISSION_GRANTED) {
12877             pw.println("Permission Denial: can't dump ActivityManager from from pid="
12878                     + Binder.getCallingPid()
12879                     + ", uid=" + Binder.getCallingUid()
12880                     + " without permission "
12881                     + android.Manifest.permission.DUMP);
12882             return;
12883         }
12884
12885         boolean dumpAll = false;
12886         boolean dumpClient = false;
12887         String dumpPackage = null;
12888
12889         int opti = 0;
12890         while (opti < args.length) {
12891             String opt = args[opti];
12892             if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12893                 break;
12894             }
12895             opti++;
12896             if ("-a".equals(opt)) {
12897                 dumpAll = true;
12898             } else if ("-c".equals(opt)) {
12899                 dumpClient = true;
12900             } else if ("-p".equals(opt)) {
12901                 if (opti < args.length) {
12902                     dumpPackage = args[opti];
12903                     opti++;
12904                 } else {
12905                     pw.println("Error: -p option requires package argument");
12906                     return;
12907                 }
12908                 dumpClient = true;
12909             } else if ("-h".equals(opt)) {
12910                 pw.println("Activity manager dump options:");
12911                 pw.println("  [-a] [-c] [-p package] [-h] [cmd] ...");
12912                 pw.println("  cmd may be one of:");
12913                 pw.println("    a[ctivities]: activity stack state");
12914                 pw.println("    r[recents]: recent activities state");
12915                 pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
12916                 pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
12917                 pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
12918                 pw.println("    o[om]: out of memory management");
12919                 pw.println("    perm[issions]: URI permission grant state");
12920                 pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
12921                 pw.println("    provider [COMP_SPEC]: provider client-side state");
12922                 pw.println("    s[ervices] [COMP_SPEC ...]: service state");
12923                 pw.println("    as[sociations]: tracked app associations");
12924                 pw.println("    service [COMP_SPEC]: service client-side state");
12925                 pw.println("    package [PACKAGE_NAME]: all state related to given package");
12926                 pw.println("    all: dump all activities");
12927                 pw.println("    top: dump the top activity");
12928                 pw.println("    write: write all pending state to storage");
12929                 pw.println("    track-associations: enable association tracking");
12930                 pw.println("    untrack-associations: disable and clear association tracking");
12931                 pw.println("  cmd may also be a COMP_SPEC to dump activities.");
12932                 pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
12933                 pw.println("    a partial substring in a component name, a");
12934                 pw.println("    hex object identifier.");
12935                 pw.println("  -a: include all available server state.");
12936                 pw.println("  -c: include client state.");
12937                 pw.println("  -p: limit output to given package.");
12938                 return;
12939             } else {
12940                 pw.println("Unknown argument: " + opt + "; use -h for help");
12941             }
12942         }
12943
12944         long origId = Binder.clearCallingIdentity();
12945         boolean more = false;
12946         // Is the caller requesting to dump a particular piece of data?
12947         if (opti < args.length) {
12948             String cmd = args[opti];
12949             opti++;
12950             if ("activities".equals(cmd) || "a".equals(cmd)) {
12951                 synchronized (this) {
12952                     dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
12953                 }
12954             } else if ("recents".equals(cmd) || "r".equals(cmd)) {
12955                 synchronized (this) {
12956                     dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
12957                 }
12958             } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
12959                 String[] newArgs;
12960                 String name;
12961                 if (opti >= args.length) {
12962                     name = null;
12963                     newArgs = EMPTY_STRING_ARRAY;
12964                 } else {
12965                     dumpPackage = args[opti];
12966                     opti++;
12967                     newArgs = new String[args.length - opti];
12968                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12969                             args.length - opti);
12970                 }
12971                 synchronized (this) {
12972                     dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
12973                 }
12974             } else if ("intents".equals(cmd) || "i".equals(cmd)) {
12975                 String[] newArgs;
12976                 String name;
12977                 if (opti >= args.length) {
12978                     name = null;
12979                     newArgs = EMPTY_STRING_ARRAY;
12980                 } else {
12981                     dumpPackage = args[opti];
12982                     opti++;
12983                     newArgs = new String[args.length - opti];
12984                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12985                             args.length - opti);
12986                 }
12987                 synchronized (this) {
12988                     dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
12989                 }
12990             } else if ("processes".equals(cmd) || "p".equals(cmd)) {
12991                 String[] newArgs;
12992                 String name;
12993                 if (opti >= args.length) {
12994                     name = null;
12995                     newArgs = EMPTY_STRING_ARRAY;
12996                 } else {
12997                     dumpPackage = args[opti];
12998                     opti++;
12999                     newArgs = new String[args.length - opti];
13000                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13001                             args.length - opti);
13002                 }
13003                 synchronized (this) {
13004                     dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
13005                 }
13006             } else if ("oom".equals(cmd) || "o".equals(cmd)) {
13007                 synchronized (this) {
13008                     dumpOomLocked(fd, pw, args, opti, true);
13009                 }
13010             } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
13011                 synchronized (this) {
13012                     dumpPermissionsLocked(fd, pw, args, opti, true, null);
13013                 }
13014             } else if ("provider".equals(cmd)) {
13015                 String[] newArgs;
13016                 String name;
13017                 if (opti >= args.length) {
13018                     name = null;
13019                     newArgs = EMPTY_STRING_ARRAY;
13020                 } else {
13021                     name = args[opti];
13022                     opti++;
13023                     newArgs = new String[args.length - opti];
13024                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13025                 }
13026                 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
13027                     pw.println("No providers match: " + name);
13028                     pw.println("Use -h for help.");
13029                 }
13030             } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
13031                 synchronized (this) {
13032                     dumpProvidersLocked(fd, pw, args, opti, true, null);
13033                 }
13034             } else if ("service".equals(cmd)) {
13035                 String[] newArgs;
13036                 String name;
13037                 if (opti >= args.length) {
13038                     name = null;
13039                     newArgs = EMPTY_STRING_ARRAY;
13040                 } else {
13041                     name = args[opti];
13042                     opti++;
13043                     newArgs = new String[args.length - opti];
13044                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13045                             args.length - opti);
13046                 }
13047                 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
13048                     pw.println("No services match: " + name);
13049                     pw.println("Use -h for help.");
13050                 }
13051             } else if ("package".equals(cmd)) {
13052                 String[] newArgs;
13053                 if (opti >= args.length) {
13054                     pw.println("package: no package name specified");
13055                     pw.println("Use -h for help.");
13056                 } else {
13057                     dumpPackage = args[opti];
13058                     opti++;
13059                     newArgs = new String[args.length - opti];
13060                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13061                             args.length - opti);
13062                     args = newArgs;
13063                     opti = 0;
13064                     more = true;
13065                 }
13066             } else if ("associations".equals(cmd) || "as".equals(cmd)) {
13067                 synchronized (this) {
13068                     dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13069                 }
13070             } else if ("services".equals(cmd) || "s".equals(cmd)) {
13071                 synchronized (this) {
13072                     mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13073                 }
13074             } else if ("write".equals(cmd)) {
13075                 mTaskPersister.flush();
13076                 pw.println("All tasks persisted.");
13077                 return;
13078             } else if ("track-associations".equals(cmd)) {
13079                 synchronized (this) {
13080                     if (!mTrackingAssociations) {
13081                         mTrackingAssociations = true;
13082                         pw.println("Association tracking started.");
13083                     } else {
13084                         pw.println("Association tracking already enabled.");
13085                     }
13086                 }
13087                 return;
13088             } else if ("untrack-associations".equals(cmd)) {
13089                 synchronized (this) {
13090                     if (mTrackingAssociations) {
13091                         mTrackingAssociations = false;
13092                         mAssociations.clear();
13093                         pw.println("Association tracking stopped.");
13094                     } else {
13095                         pw.println("Association tracking not running.");
13096                     }
13097                 }
13098                 return;
13099             } else {
13100                 // Dumping a single activity?
13101                 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
13102                     pw.println("Bad activity command, or no activities match: " + cmd);
13103                     pw.println("Use -h for help.");
13104                 }
13105             }
13106             if (!more) {
13107                 Binder.restoreCallingIdentity(origId);
13108                 return;
13109             }
13110         }
13111
13112         // No piece of data specified, dump everything.
13113         synchronized (this) {
13114             dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13115             pw.println();
13116             if (dumpAll) {
13117                 pw.println("-------------------------------------------------------------------------------");
13118             }
13119             dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13120             pw.println();
13121             if (dumpAll) {
13122                 pw.println("-------------------------------------------------------------------------------");
13123             }
13124             dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13125             pw.println();
13126             if (dumpAll) {
13127                 pw.println("-------------------------------------------------------------------------------");
13128             }
13129             dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13130             pw.println();
13131             if (dumpAll) {
13132                 pw.println("-------------------------------------------------------------------------------");
13133             }
13134             mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13135             pw.println();
13136             if (dumpAll) {
13137                 pw.println("-------------------------------------------------------------------------------");
13138             }
13139             dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13140             pw.println();
13141             if (dumpAll) {
13142                 pw.println("-------------------------------------------------------------------------------");
13143             }
13144             dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13145             if (mAssociations.size() > 0) {
13146                 pw.println();
13147                 if (dumpAll) {
13148                     pw.println("-------------------------------------------------------------------------------");
13149                 }
13150                 dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13151             }
13152             pw.println();
13153             if (dumpAll) {
13154                 pw.println("-------------------------------------------------------------------------------");
13155             }
13156             dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13157         }
13158         Binder.restoreCallingIdentity(origId);
13159     }
13160
13161     void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13162             int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
13163         pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
13164
13165         boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
13166                 dumpPackage);
13167         boolean needSep = printedAnything;
13168
13169         boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
13170                 dumpPackage, needSep, "  mFocusedActivity: ");
13171         if (printed) {
13172             printedAnything = true;
13173             needSep = false;
13174         }
13175
13176         if (dumpPackage == null) {
13177             if (needSep) {
13178                 pw.println();
13179             }
13180             needSep = true;
13181             printedAnything = true;
13182             mStackSupervisor.dump(pw, "  ");
13183         }
13184
13185         if (!printedAnything) {
13186             pw.println("  (nothing)");
13187         }
13188     }
13189
13190     void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13191             int opti, boolean dumpAll, String dumpPackage) {
13192         pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
13193
13194         boolean printedAnything = false;
13195
13196         if (mRecentTasks != null && mRecentTasks.size() > 0) {
13197             boolean printedHeader = false;
13198
13199             final int N = mRecentTasks.size();
13200             for (int i=0; i<N; i++) {
13201                 TaskRecord tr = mRecentTasks.get(i);
13202                 if (dumpPackage != null) {
13203                     if (tr.realActivity == null ||
13204                             !dumpPackage.equals(tr.realActivity)) {
13205                         continue;
13206                     }
13207                 }
13208                 if (!printedHeader) {
13209                     pw.println("  Recent tasks:");
13210                     printedHeader = true;
13211                     printedAnything = true;
13212                 }
13213                 pw.print("  * Recent #"); pw.print(i); pw.print(": ");
13214                         pw.println(tr);
13215                 if (dumpAll) {
13216                     mRecentTasks.get(i).dump(pw, "    ");
13217                 }
13218             }
13219         }
13220
13221         if (!printedAnything) {
13222             pw.println("  (nothing)");
13223         }
13224     }
13225
13226     void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13227             int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
13228         pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
13229
13230         int dumpUid = 0;
13231         if (dumpPackage != null) {
13232             IPackageManager pm = AppGlobals.getPackageManager();
13233             try {
13234                 dumpUid = pm.getPackageUid(dumpPackage, 0);
13235             } catch (RemoteException e) {
13236             }
13237         }
13238
13239         boolean printedAnything = false;
13240
13241         final long now = SystemClock.uptimeMillis();
13242
13243         for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
13244             ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
13245                     = mAssociations.valueAt(i1);
13246             for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
13247                 SparseArray<ArrayMap<String, Association>> sourceUids
13248                         = targetComponents.valueAt(i2);
13249                 for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
13250                     ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
13251                     for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
13252                         Association ass = sourceProcesses.valueAt(i4);
13253                         if (dumpPackage != null) {
13254                             if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
13255                                     && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
13256                                 continue;
13257                             }
13258                         }
13259                         printedAnything = true;
13260                         pw.print("  ");
13261                         pw.print(ass.mTargetProcess);
13262                         pw.print("/");
13263                         UserHandle.formatUid(pw, ass.mTargetUid);
13264                         pw.print(" <- ");
13265                         pw.print(ass.mSourceProcess);
13266                         pw.print("/");
13267                         UserHandle.formatUid(pw, ass.mSourceUid);
13268                         pw.println();
13269                         pw.print("    via ");
13270                         pw.print(ass.mTargetComponent.flattenToShortString());
13271                         pw.println();
13272                         pw.print("    ");
13273                         long dur = ass.mTime;
13274                         if (ass.mNesting > 0) {
13275                             dur += now - ass.mStartTime;
13276                         }
13277                         TimeUtils.formatDuration(dur, pw);
13278                         pw.print(" (");
13279                         pw.print(ass.mCount);
13280                         pw.println(" times)");
13281                         if (ass.mNesting > 0) {
13282                             pw.print("    ");
13283                             pw.print(" Currently active: ");
13284                             TimeUtils.formatDuration(now - ass.mStartTime, pw);
13285                             pw.println();
13286                         }
13287                     }
13288                 }
13289             }
13290
13291         }
13292
13293         if (!printedAnything) {
13294             pw.println("  (nothing)");
13295         }
13296     }
13297
13298     void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13299             int opti, boolean dumpAll, String dumpPackage) {
13300         boolean needSep = false;
13301         boolean printedAnything = false;
13302         int numPers = 0;
13303
13304         pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
13305
13306         if (dumpAll) {
13307             final int NP = mProcessNames.getMap().size();
13308             for (int ip=0; ip<NP; ip++) {
13309                 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
13310                 final int NA = procs.size();
13311                 for (int ia=0; ia<NA; ia++) {
13312                     ProcessRecord r = procs.valueAt(ia);
13313                     if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13314                         continue;
13315                     }
13316                     if (!needSep) {
13317                         pw.println("  All known processes:");
13318                         needSep = true;
13319                         printedAnything = true;
13320                     }
13321                     pw.print(r.persistent ? "  *PERS*" : "  *APP*");
13322                         pw.print(" UID "); pw.print(procs.keyAt(ia));
13323                         pw.print(" "); pw.println(r);
13324                     r.dump(pw, "    ");
13325                     if (r.persistent) {
13326                         numPers++;
13327                     }
13328                 }
13329             }
13330         }
13331
13332         if (mIsolatedProcesses.size() > 0) {
13333             boolean printed = false;
13334             for (int i=0; i<mIsolatedProcesses.size(); i++) {
13335                 ProcessRecord r = mIsolatedProcesses.valueAt(i);
13336                 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13337                     continue;
13338                 }
13339                 if (!printed) {
13340                     if (needSep) {
13341                         pw.println();
13342                     }
13343                     pw.println("  Isolated process list (sorted by uid):");
13344                     printedAnything = true;
13345                     printed = true;
13346                     needSep = true;
13347                 }
13348                 pw.println(String.format("%sIsolated #%2d: %s",
13349                         "    ", i, r.toString()));
13350             }
13351         }
13352
13353         if (mActiveUids.size() > 0) {
13354             if (needSep) {
13355                 pw.println();
13356             }
13357             pw.println("  UID states:");
13358             for (int i=0; i<mActiveUids.size(); i++) {
13359                 UidRecord uidRec = mActiveUids.valueAt(i);
13360                 pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
13361                 pw.print(": "); pw.println(uidRec);
13362             }
13363             needSep = true;
13364             printedAnything = true;
13365         }
13366
13367         if (mLruProcesses.size() > 0) {
13368             if (needSep) {
13369                 pw.println();
13370             }
13371             pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
13372                     pw.print(" total, non-act at ");
13373                     pw.print(mLruProcesses.size()-mLruProcessActivityStart);
13374                     pw.print(", non-svc at ");
13375                     pw.print(mLruProcesses.size()-mLruProcessServiceStart);
13376                     pw.println("):");
13377             dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
13378             needSep = true;
13379             printedAnything = true;
13380         }
13381
13382         if (dumpAll || dumpPackage != null) {
13383             synchronized (mPidsSelfLocked) {
13384                 boolean printed = false;
13385                 for (int i=0; i<mPidsSelfLocked.size(); i++) {
13386                     ProcessRecord r = mPidsSelfLocked.valueAt(i);
13387                     if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13388                         continue;
13389                     }
13390                     if (!printed) {
13391                         if (needSep) pw.println();
13392                         needSep = true;
13393                         pw.println("  PID mappings:");
13394                         printed = true;
13395                         printedAnything = true;
13396                     }
13397                     pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
13398                         pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
13399                 }
13400             }
13401         }
13402
13403         if (mForegroundProcesses.size() > 0) {
13404             synchronized (mPidsSelfLocked) {
13405                 boolean printed = false;
13406                 for (int i=0; i<mForegroundProcesses.size(); i++) {
13407                     ProcessRecord r = mPidsSelfLocked.get(
13408                             mForegroundProcesses.valueAt(i).pid);
13409                     if (dumpPackage != null && (r == null
13410                             || !r.pkgList.containsKey(dumpPackage))) {
13411                         continue;
13412                     }
13413                     if (!printed) {
13414                         if (needSep) pw.println();
13415                         needSep = true;
13416                         pw.println("  Foreground Processes:");
13417                         printed = true;
13418                         printedAnything = true;
13419                     }
13420                     pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
13421                             pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
13422                 }
13423             }
13424         }
13425
13426         if (mPersistentStartingProcesses.size() > 0) {
13427             if (needSep) pw.println();
13428             needSep = true;
13429             printedAnything = true;
13430             pw.println("  Persisent processes that are starting:");
13431             dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
13432                     "Starting Norm", "Restarting PERS", dumpPackage);
13433         }
13434
13435         if (mRemovedProcesses.size() > 0) {
13436             if (needSep) pw.println();
13437             needSep = true;
13438             printedAnything = true;
13439             pw.println("  Processes that are being removed:");
13440             dumpProcessList(pw, this, mRemovedProcesses, "    ",
13441                     "Removed Norm", "Removed PERS", dumpPackage);
13442         }
13443
13444         if (mProcessesOnHold.size() > 0) {
13445             if (needSep) pw.println();
13446             needSep = true;
13447             printedAnything = true;
13448             pw.println("  Processes that are on old until the system is ready:");
13449             dumpProcessList(pw, this, mProcessesOnHold, "    ",
13450                     "OnHold Norm", "OnHold PERS", dumpPackage);
13451         }
13452
13453         needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
13454
13455         if (mProcessCrashTimes.getMap().size() > 0) {
13456             boolean printed = false;
13457             long now = SystemClock.uptimeMillis();
13458             final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
13459             final int NP = pmap.size();
13460             for (int ip=0; ip<NP; ip++) {
13461                 String pname = pmap.keyAt(ip);
13462                 SparseArray<Long> uids = pmap.valueAt(ip);
13463                 final int N = uids.size();
13464                 for (int i=0; i<N; i++) {
13465                     int puid = uids.keyAt(i);
13466                     ProcessRecord r = mProcessNames.get(pname, puid);
13467                     if (dumpPackage != null && (r == null
13468                             || !r.pkgList.containsKey(dumpPackage))) {
13469                         continue;
13470                     }
13471                     if (!printed) {
13472                         if (needSep) pw.println();
13473                         needSep = true;
13474                         pw.println("  Time since processes crashed:");
13475                         printed = true;
13476                         printedAnything = true;
13477                     }
13478                     pw.print("    Process "); pw.print(pname);
13479                             pw.print(" uid "); pw.print(puid);
13480                             pw.print(": last crashed ");
13481                             TimeUtils.formatDuration(now-uids.valueAt(i), pw);
13482                             pw.println(" ago");
13483                 }
13484             }
13485         }
13486
13487         if (mBadProcesses.getMap().size() > 0) {
13488             boolean printed = false;
13489             final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
13490             final int NP = pmap.size();
13491             for (int ip=0; ip<NP; ip++) {
13492                 String pname = pmap.keyAt(ip);
13493                 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
13494                 final int N = uids.size();
13495                 for (int i=0; i<N; i++) {
13496                     int puid = uids.keyAt(i);
13497                     ProcessRecord r = mProcessNames.get(pname, puid);
13498                     if (dumpPackage != null && (r == null
13499                             || !r.pkgList.containsKey(dumpPackage))) {
13500                         continue;
13501                     }
13502                     if (!printed) {
13503                         if (needSep) pw.println();
13504                         needSep = true;
13505                         pw.println("  Bad processes:");
13506                         printedAnything = true;
13507                     }
13508                     BadProcessInfo info = uids.valueAt(i);
13509                     pw.print("    Bad process "); pw.print(pname);
13510                             pw.print(" uid "); pw.print(puid);
13511                             pw.print(": crashed at time "); pw.println(info.time);
13512                     if (info.shortMsg != null) {
13513                         pw.print("      Short msg: "); pw.println(info.shortMsg);
13514                     }
13515                     if (info.longMsg != null) {
13516                         pw.print("      Long msg: "); pw.println(info.longMsg);
13517                     }
13518                     if (info.stack != null) {
13519                         pw.println("      Stack:");
13520                         int lastPos = 0;
13521                         for (int pos=0; pos<info.stack.length(); pos++) {
13522                             if (info.stack.charAt(pos) == '\n') {
13523                                 pw.print("        ");
13524                                 pw.write(info.stack, lastPos, pos-lastPos);
13525                                 pw.println();
13526                                 lastPos = pos+1;
13527                             }
13528                         }
13529                         if (lastPos < info.stack.length()) {
13530                             pw.print("        ");
13531                             pw.write(info.stack, lastPos, info.stack.length()-lastPos);
13532                             pw.println();
13533                         }
13534                     }
13535                 }
13536             }
13537         }
13538
13539         if (dumpPackage == null) {
13540             pw.println();
13541             needSep = false;
13542             pw.println("  mStartedUsers:");
13543             for (int i=0; i<mStartedUsers.size(); i++) {
13544                 UserState uss = mStartedUsers.valueAt(i);
13545                 pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
13546                         pw.print(": "); uss.dump("", pw);
13547             }
13548             pw.print("  mStartedUserArray: [");
13549             for (int i=0; i<mStartedUserArray.length; i++) {
13550                 if (i > 0) pw.print(", ");
13551                 pw.print(mStartedUserArray[i]);
13552             }
13553             pw.println("]");
13554             pw.print("  mUserLru: [");
13555             for (int i=0; i<mUserLru.size(); i++) {
13556                 if (i > 0) pw.print(", ");
13557                 pw.print(mUserLru.get(i));
13558             }
13559             pw.println("]");
13560             if (dumpAll) {
13561                 pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
13562             }
13563             synchronized (mUserProfileGroupIdsSelfLocked) {
13564                 if (mUserProfileGroupIdsSelfLocked.size() > 0) {
13565                     pw.println("  mUserProfileGroupIds:");
13566                     for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
13567                         pw.print("    User #");
13568                         pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
13569                         pw.print(" -> profile #");
13570                         pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
13571                     }
13572                 }
13573             }
13574         }
13575         if (mHomeProcess != null && (dumpPackage == null
13576                 || mHomeProcess.pkgList.containsKey(dumpPackage))) {
13577             if (needSep) {
13578                 pw.println();
13579                 needSep = false;
13580             }
13581             pw.println("  mHomeProcess: " + mHomeProcess);
13582         }
13583         if (mPreviousProcess != null && (dumpPackage == null
13584                 || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
13585             if (needSep) {
13586                 pw.println();
13587                 needSep = false;
13588             }
13589             pw.println("  mPreviousProcess: " + mPreviousProcess);
13590         }
13591         if (dumpAll) {
13592             StringBuilder sb = new StringBuilder(128);
13593             sb.append("  mPreviousProcessVisibleTime: ");
13594             TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
13595             pw.println(sb);
13596         }
13597         if (mHeavyWeightProcess != null && (dumpPackage == null
13598                 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
13599             if (needSep) {
13600                 pw.println();
13601                 needSep = false;
13602             }
13603             pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
13604         }
13605         if (dumpPackage == null) {
13606             pw.println("  mConfiguration: " + mConfiguration);
13607         }
13608         if (dumpAll) {
13609             pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
13610             if (mCompatModePackages.getPackages().size() > 0) {
13611                 boolean printed = false;
13612                 for (Map.Entry<String, Integer> entry
13613                         : mCompatModePackages.getPackages().entrySet()) {
13614                     String pkg = entry.getKey();
13615                     int mode = entry.getValue();
13616                     if (dumpPackage != null && !dumpPackage.equals(pkg)) {
13617                         continue;
13618                     }
13619                     if (!printed) {
13620                         pw.println("  mScreenCompatPackages:");
13621                         printed = true;
13622                     }
13623                     pw.print("    "); pw.print(pkg); pw.print(": ");
13624                             pw.print(mode); pw.println();
13625                 }
13626             }
13627         }
13628         if (dumpPackage == null) {
13629             pw.println("  mWakefulness="
13630                     + PowerManagerInternal.wakefulnessToString(mWakefulness));
13631             pw.println("  mSleepTokens=" + mSleepTokens);
13632             pw.println("  mSleeping=" + mSleeping + " mLockScreenShown="
13633                     + lockScreenShownToString());
13634             pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
13635             if (mRunningVoice != null) {
13636                 pw.println("  mRunningVoice=" + mRunningVoice);
13637                 pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
13638             }
13639         }
13640         if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
13641                 || mOrigWaitForDebugger) {
13642             if (dumpPackage == null || dumpPackage.equals(mDebugApp)
13643                     || dumpPackage.equals(mOrigDebugApp)) {
13644                 if (needSep) {
13645                     pw.println();
13646                     needSep = false;
13647                 }
13648                 pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
13649                         + " mDebugTransient=" + mDebugTransient
13650                         + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
13651             }
13652         }
13653         if (mCurAppTimeTracker != null) {
13654             mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
13655         }
13656         if (mMemWatchProcesses.getMap().size() > 0) {
13657             pw.println("  Mem watch processes:");
13658             final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
13659                     = mMemWatchProcesses.getMap();
13660             for (int i=0; i<procs.size(); i++) {
13661                 final String proc = procs.keyAt(i);
13662                 final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
13663                 for (int j=0; j<uids.size(); j++) {
13664                     if (needSep) {
13665                         pw.println();
13666                         needSep = false;
13667                     }
13668                     StringBuilder sb = new StringBuilder();
13669                     sb.append("    ").append(proc).append('/');
13670                     UserHandle.formatUid(sb, uids.keyAt(j));
13671                     Pair<Long, String> val = uids.valueAt(j);
13672                     sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
13673                     if (val.second != null) {
13674                         sb.append(", report to ").append(val.second);
13675                     }
13676                     pw.println(sb.toString());
13677                 }
13678             }
13679             pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
13680             pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
13681             pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
13682                     pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
13683         }
13684         if (mOpenGlTraceApp != null) {
13685             if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
13686                 if (needSep) {
13687                     pw.println();
13688                     needSep = false;
13689                 }
13690                 pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
13691             }
13692         }
13693         if (mProfileApp != null || mProfileProc != null || mProfileFile != null
13694                 || mProfileFd != null) {
13695             if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
13696                 if (needSep) {
13697                     pw.println();
13698                     needSep = false;
13699                 }
13700                 pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
13701                 pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
13702                 pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
13703                         + mAutoStopProfiler);
13704                 pw.println("  mProfileType=" + mProfileType);
13705             }
13706         }
13707         if (dumpPackage == null) {
13708             if (mAlwaysFinishActivities || mController != null) {
13709                 pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
13710                         + " mController=" + mController);
13711             }
13712             if (dumpAll) {
13713                 pw.println("  Total persistent processes: " + numPers);
13714                 pw.println("  mProcessesReady=" + mProcessesReady
13715                         + " mSystemReady=" + mSystemReady
13716                         + " mBooted=" + mBooted
13717                         + " mFactoryTest=" + mFactoryTest);
13718                 pw.println("  mBooting=" + mBooting
13719                         + " mCallFinishBooting=" + mCallFinishBooting
13720                         + " mBootAnimationComplete=" + mBootAnimationComplete);
13721                 pw.print("  mLastPowerCheckRealtime=");
13722                         TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
13723                         pw.println("");
13724                 pw.print("  mLastPowerCheckUptime=");
13725                         TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
13726                         pw.println("");
13727                 pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
13728                 pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
13729                 pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
13730                 pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
13731                         + " (" + mLruProcesses.size() + " total)"
13732                         + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
13733                         + " mNumServiceProcs=" + mNumServiceProcs
13734                         + " mNewNumServiceProcs=" + mNewNumServiceProcs);
13735                 pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
13736                         + " mLastMemoryLevel" + mLastMemoryLevel
13737                         + " mLastNumProcesses" + mLastNumProcesses);
13738                 long now = SystemClock.uptimeMillis();
13739                 pw.print("  mLastIdleTime=");
13740                         TimeUtils.formatDuration(now, mLastIdleTime, pw);
13741                         pw.print(" mLowRamSinceLastIdle=");
13742                         TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
13743                         pw.println();
13744             }
13745         }
13746
13747         if (!printedAnything) {
13748             pw.println("  (nothing)");
13749         }
13750     }
13751
13752     boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
13753             int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
13754         if (mProcessesToGc.size() > 0) {
13755             boolean printed = false;
13756             long now = SystemClock.uptimeMillis();
13757             for (int i=0; i<mProcessesToGc.size(); i++) {
13758                 ProcessRecord proc = mProcessesToGc.get(i);
13759                 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
13760                     continue;
13761                 }
13762                 if (!printed) {
13763                     if (needSep) pw.println();
13764                     needSep = true;
13765                     pw.println("  Processes that are waiting to GC:");
13766                     printed = true;
13767                 }
13768                 pw.print("    Process "); pw.println(proc);
13769                 pw.print("      lowMem="); pw.print(proc.reportLowMemory);
13770                         pw.print(", last gced=");
13771                         pw.print(now-proc.lastRequestedGc);
13772                         pw.print(" ms ago, last lowMem=");
13773                         pw.print(now-proc.lastLowMemory);
13774                         pw.println(" ms ago");
13775
13776             }
13777         }
13778         return needSep;
13779     }
13780
13781     void printOomLevel(PrintWriter pw, String name, int adj) {
13782         pw.print("    ");
13783         if (adj >= 0) {
13784             pw.print(' ');
13785             if (adj < 10) pw.print(' ');
13786         } else {
13787             if (adj > -10) pw.print(' ');
13788         }
13789         pw.print(adj);
13790         pw.print(": ");
13791         pw.print(name);
13792         pw.print(" (");
13793         pw.print(mProcessList.getMemLevel(adj)/1024);
13794         pw.println(" kB)");
13795     }
13796
13797     boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13798             int opti, boolean dumpAll) {
13799         boolean needSep = false;
13800
13801         if (mLruProcesses.size() > 0) {
13802             if (needSep) pw.println();
13803             needSep = true;
13804             pw.println("  OOM levels:");
13805             printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
13806             printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
13807             printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
13808             printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
13809             printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
13810             printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
13811             printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
13812             printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
13813             printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
13814             printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
13815             printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
13816             printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
13817             printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
13818             printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
13819
13820             if (needSep) pw.println();
13821             pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
13822                     pw.print(" total, non-act at ");
13823                     pw.print(mLruProcesses.size()-mLruProcessActivityStart);
13824                     pw.print(", non-svc at ");
13825                     pw.print(mLruProcesses.size()-mLruProcessServiceStart);
13826                     pw.println("):");
13827             dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
13828             needSep = true;
13829         }
13830
13831         dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
13832
13833         pw.println();
13834         pw.println("  mHomeProcess: " + mHomeProcess);
13835         pw.println("  mPreviousProcess: " + mPreviousProcess);
13836         if (mHeavyWeightProcess != null) {
13837             pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
13838         }
13839
13840         return true;
13841     }
13842
13843     /**
13844      * There are three ways to call this:
13845      *  - no provider specified: dump all the providers
13846      *  - a flattened component name that matched an existing provider was specified as the
13847      *    first arg: dump that one provider
13848      *  - the first arg isn't the flattened component name of an existing provider:
13849      *    dump all providers whose component contains the first arg as a substring
13850      */
13851     protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13852             int opti, boolean dumpAll) {
13853         return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
13854     }
13855
13856     static class ItemMatcher {
13857         ArrayList<ComponentName> components;
13858         ArrayList<String> strings;
13859         ArrayList<Integer> objects;
13860         boolean all;
13861
13862         ItemMatcher() {
13863             all = true;
13864         }
13865
13866         void build(String name) {
13867             ComponentName componentName = ComponentName.unflattenFromString(name);
13868             if (componentName != null) {
13869                 if (components == null) {
13870                     components = new ArrayList<ComponentName>();
13871                 }
13872                 components.add(componentName);
13873                 all = false;
13874             } else {
13875                 int objectId = 0;
13876                 // Not a '/' separated full component name; maybe an object ID?
13877                 try {
13878                     objectId = Integer.parseInt(name, 16);
13879                     if (objects == null) {
13880                         objects = new ArrayList<Integer>();
13881                     }
13882                     objects.add(objectId);
13883                     all = false;
13884                 } catch (RuntimeException e) {
13885                     // Not an integer; just do string match.
13886                     if (strings == null) {
13887                         strings = new ArrayList<String>();
13888                     }
13889                     strings.add(name);
13890                     all = false;
13891                 }
13892             }
13893         }
13894
13895         int build(String[] args, int opti) {
13896             for (; opti<args.length; opti++) {
13897                 String name = args[opti];
13898                 if ("--".equals(name)) {
13899                     return opti+1;
13900                 }
13901                 build(name);
13902             }
13903             return opti;
13904         }
13905
13906         boolean match(Object object, ComponentName comp) {
13907             if (all) {
13908                 return true;
13909             }
13910             if (components != null) {
13911                 for (int i=0; i<components.size(); i++) {
13912                     if (components.get(i).equals(comp)) {
13913                         return true;
13914                     }
13915                 }
13916             }
13917             if (objects != null) {
13918                 for (int i=0; i<objects.size(); i++) {
13919                     if (System.identityHashCode(object) == objects.get(i)) {
13920                         return true;
13921                     }
13922                 }
13923             }
13924             if (strings != null) {
13925                 String flat = comp.flattenToString();
13926                 for (int i=0; i<strings.size(); i++) {
13927                     if (flat.contains(strings.get(i))) {
13928                         return true;
13929                     }
13930                 }
13931             }
13932             return false;
13933         }
13934     }
13935
13936     /**
13937      * There are three things that cmd can be:
13938      *  - a flattened component name that matches an existing activity
13939      *  - the cmd arg isn't the flattened component name of an existing activity:
13940      *    dump all activity whose component contains the cmd as a substring
13941      *  - A hex number of the ActivityRecord object instance.
13942      */
13943     protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13944             int opti, boolean dumpAll) {
13945         ArrayList<ActivityRecord> activities;
13946
13947         synchronized (this) {
13948             activities = mStackSupervisor.getDumpActivitiesLocked(name);
13949         }
13950
13951         if (activities.size() <= 0) {
13952             return false;
13953         }
13954
13955         String[] newArgs = new String[args.length - opti];
13956         System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13957
13958         TaskRecord lastTask = null;
13959         boolean needSep = false;
13960         for (int i=activities.size()-1; i>=0; i--) {
13961             ActivityRecord r = activities.get(i);
13962             if (needSep) {
13963                 pw.println();
13964             }
13965             needSep = true;
13966             synchronized (this) {
13967                 if (lastTask != r.task) {
13968                     lastTask = r.task;
13969                     pw.print("TASK "); pw.print(lastTask.affinity);
13970                             pw.print(" id="); pw.println(lastTask.taskId);
13971                     if (dumpAll) {
13972                         lastTask.dump(pw, "  ");
13973                     }
13974                 }
13975             }
13976             dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
13977         }
13978         return true;
13979     }
13980
13981     /**
13982      * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
13983      * there is a thread associated with the activity.
13984      */
13985     private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
13986             final ActivityRecord r, String[] args, boolean dumpAll) {
13987         String innerPrefix = prefix + "  ";
13988         synchronized (this) {
13989             pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
13990                     pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
13991                     pw.print(" pid=");
13992                     if (r.app != null) pw.println(r.app.pid);
13993                     else pw.println("(not running)");
13994             if (dumpAll) {
13995                 r.dump(pw, innerPrefix);
13996             }
13997         }
13998         if (r.app != null && r.app.thread != null) {
13999             // flush anything that is already in the PrintWriter since the thread is going
14000             // to write to the file descriptor directly
14001             pw.flush();
14002             try {
14003                 TransferPipe tp = new TransferPipe();
14004                 try {
14005                     r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
14006                             r.appToken, innerPrefix, args);
14007                     tp.go(fd);
14008                 } finally {
14009                     tp.kill();
14010                 }
14011             } catch (IOException e) {
14012                 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
14013             } catch (RemoteException e) {
14014                 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
14015             }
14016         }
14017     }
14018
14019     void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14020             int opti, boolean dumpAll, String dumpPackage) {
14021         boolean needSep = false;
14022         boolean onlyHistory = false;
14023         boolean printedAnything = false;
14024
14025         if ("history".equals(dumpPackage)) {
14026             if (opti < args.length && "-s".equals(args[opti])) {
14027                 dumpAll = false;
14028             }
14029             onlyHistory = true;
14030             dumpPackage = null;
14031         }
14032
14033         pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
14034         if (!onlyHistory && dumpAll) {
14035             if (mRegisteredReceivers.size() > 0) {
14036                 boolean printed = false;
14037                 Iterator it = mRegisteredReceivers.values().iterator();
14038                 while (it.hasNext()) {
14039                     ReceiverList r = (ReceiverList)it.next();
14040                     if (dumpPackage != null && (r.app == null ||
14041                             !dumpPackage.equals(r.app.info.packageName))) {
14042                         continue;
14043                     }
14044                     if (!printed) {
14045                         pw.println("  Registered Receivers:");
14046                         needSep = true;
14047                         printed = true;
14048                         printedAnything = true;
14049                     }
14050                     pw.print("  * "); pw.println(r);
14051                     r.dump(pw, "    ");
14052                 }
14053             }
14054
14055             if (mReceiverResolver.dump(pw, needSep ?
14056                     "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
14057                     "    ", dumpPackage, false, false)) {
14058                 needSep = true;
14059                 printedAnything = true;
14060             }
14061         }
14062
14063         for (BroadcastQueue q : mBroadcastQueues) {
14064             needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
14065             printedAnything |= needSep;
14066         }
14067
14068         needSep = true;
14069
14070         if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
14071             for (int user=0; user<mStickyBroadcasts.size(); user++) {
14072                 if (needSep) {
14073                     pw.println();
14074                 }
14075                 needSep = true;
14076                 printedAnything = true;
14077                 pw.print("  Sticky broadcasts for user ");
14078                         pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
14079                 StringBuilder sb = new StringBuilder(128);
14080                 for (Map.Entry<String, ArrayList<Intent>> ent
14081                         : mStickyBroadcasts.valueAt(user).entrySet()) {
14082                     pw.print("  * Sticky action "); pw.print(ent.getKey());
14083                     if (dumpAll) {
14084                         pw.println(":");
14085                         ArrayList<Intent> intents = ent.getValue();
14086                         final int N = intents.size();
14087                         for (int i=0; i<N; i++) {
14088                             sb.setLength(0);
14089                             sb.append("    Intent: ");
14090                             intents.get(i).toShortString(sb, false, true, false, false);
14091                             pw.println(sb.toString());
14092                             Bundle bundle = intents.get(i).getExtras();
14093                             if (bundle != null) {
14094                                 pw.print("      ");
14095                                 pw.println(bundle.toString());
14096                             }
14097                         }
14098                     } else {
14099                         pw.println("");
14100                     }
14101                 }
14102             }
14103         }
14104
14105         if (!onlyHistory && dumpAll) {
14106             pw.println();
14107             for (BroadcastQueue queue : mBroadcastQueues) {
14108                 pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
14109                         + queue.mBroadcastsScheduled);
14110             }
14111             pw.println("  mHandler:");
14112             mHandler.dump(new PrintWriterPrinter(pw), "    ");
14113             needSep = true;
14114             printedAnything = true;
14115         }
14116
14117         if (!printedAnything) {
14118             pw.println("  (nothing)");
14119         }
14120     }
14121
14122     void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14123             int opti, boolean dumpAll, String dumpPackage) {
14124         boolean needSep;
14125         boolean printedAnything = false;
14126
14127         ItemMatcher matcher = new ItemMatcher();
14128         matcher.build(args, opti);
14129
14130         pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
14131
14132         needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
14133         printedAnything |= needSep;
14134
14135         if (mLaunchingProviders.size() > 0) {
14136             boolean printed = false;
14137             for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
14138                 ContentProviderRecord r = mLaunchingProviders.get(i);
14139                 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
14140                     continue;
14141                 }
14142                 if (!printed) {
14143                     if (needSep) pw.println();
14144                     needSep = true;
14145                     pw.println("  Launching content providers:");
14146                     printed = true;
14147                     printedAnything = true;
14148                 }
14149                 pw.print("  Launching #"); pw.print(i); pw.print(": ");
14150                         pw.println(r);
14151             }
14152         }
14153
14154         if (!printedAnything) {
14155             pw.println("  (nothing)");
14156         }
14157     }
14158
14159     void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14160             int opti, boolean dumpAll, String dumpPackage) {
14161         boolean needSep = false;
14162         boolean printedAnything = false;
14163
14164         pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
14165
14166         if (mGrantedUriPermissions.size() > 0) {
14167             boolean printed = false;
14168             int dumpUid = -2;
14169             if (dumpPackage != null) {
14170                 try {
14171                     dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
14172                 } catch (NameNotFoundException e) {
14173                     dumpUid = -1;
14174                 }
14175             }
14176             for (int i=0; i<mGrantedUriPermissions.size(); i++) {
14177                 int uid = mGrantedUriPermissions.keyAt(i);
14178                 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
14179                     continue;
14180                 }
14181                 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
14182                 if (!printed) {
14183                     if (needSep) pw.println();
14184                     needSep = true;
14185                     pw.println("  Granted Uri Permissions:");
14186                     printed = true;
14187                     printedAnything = true;
14188                 }
14189                 pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
14190                 for (UriPermission perm : perms.values()) {
14191                     pw.print("    "); pw.println(perm);
14192                     if (dumpAll) {
14193                         perm.dump(pw, "      ");
14194                     }
14195                 }
14196             }
14197         }
14198
14199         if (!printedAnything) {
14200             pw.println("  (nothing)");
14201         }
14202     }
14203
14204     void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14205             int opti, boolean dumpAll, String dumpPackage) {
14206         boolean printed = false;
14207
14208         pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
14209
14210         if (mIntentSenderRecords.size() > 0) {
14211             Iterator<WeakReference<PendingIntentRecord>> it
14212                     = mIntentSenderRecords.values().iterator();
14213             while (it.hasNext()) {
14214                 WeakReference<PendingIntentRecord> ref = it.next();
14215                 PendingIntentRecord rec = ref != null ? ref.get(): null;
14216                 if (dumpPackage != null && (rec == null
14217                         || !dumpPackage.equals(rec.key.packageName))) {
14218                     continue;
14219                 }
14220                 printed = true;
14221                 if (rec != null) {
14222                     pw.print("  * "); pw.println(rec);
14223                     if (dumpAll) {
14224                         rec.dump(pw, "    ");
14225                     }
14226                 } else {
14227                     pw.print("  * "); pw.println(ref);
14228                 }
14229             }
14230         }
14231
14232         if (!printed) {
14233             pw.println("  (nothing)");
14234         }
14235     }
14236
14237     private static final int dumpProcessList(PrintWriter pw,
14238             ActivityManagerService service, List list,
14239             String prefix, String normalLabel, String persistentLabel,
14240             String dumpPackage) {
14241         int numPers = 0;
14242         final int N = list.size()-1;
14243         for (int i=N; i>=0; i--) {
14244             ProcessRecord r = (ProcessRecord)list.get(i);
14245             if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
14246                 continue;
14247             }
14248             pw.println(String.format("%s%s #%2d: %s",
14249                     prefix, (r.persistent ? persistentLabel : normalLabel),
14250                     i, r.toString()));
14251             if (r.persistent) {
14252                 numPers++;
14253             }
14254         }
14255         return numPers;
14256     }
14257
14258     private static final boolean dumpProcessOomList(PrintWriter pw,
14259             ActivityManagerService service, List<ProcessRecord> origList,
14260             String prefix, String normalLabel, String persistentLabel,
14261             boolean inclDetails, String dumpPackage) {
14262
14263         ArrayList<Pair<ProcessRecord, Integer>> list
14264                 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
14265         for (int i=0; i<origList.size(); i++) {
14266             ProcessRecord r = origList.get(i);
14267             if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14268                 continue;
14269             }
14270             list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
14271         }
14272
14273         if (list.size() <= 0) {
14274             return false;
14275         }
14276
14277         Comparator<Pair<ProcessRecord, Integer>> comparator
14278                 = new Comparator<Pair<ProcessRecord, Integer>>() {
14279             @Override
14280             public int compare(Pair<ProcessRecord, Integer> object1,
14281                     Pair<ProcessRecord, Integer> object2) {
14282                 if (object1.first.setAdj != object2.first.setAdj) {
14283                     return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
14284                 }
14285                 if (object1.second.intValue() != object2.second.intValue()) {
14286                     return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
14287                 }
14288                 return 0;
14289             }
14290         };
14291
14292         Collections.sort(list, comparator);
14293
14294         final long curRealtime = SystemClock.elapsedRealtime();
14295         final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
14296         final long curUptime = SystemClock.uptimeMillis();
14297         final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
14298
14299         for (int i=list.size()-1; i>=0; i--) {
14300             ProcessRecord r = list.get(i).first;
14301             String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
14302             char schedGroup;
14303             switch (r.setSchedGroup) {
14304                 case Process.THREAD_GROUP_BG_NONINTERACTIVE:
14305                     schedGroup = 'B';
14306                     break;
14307                 case Process.THREAD_GROUP_DEFAULT:
14308                     schedGroup = 'F';
14309                     break;
14310                 default:
14311                     schedGroup = '?';
14312                     break;
14313             }
14314             char foreground;
14315             if (r.foregroundActivities) {
14316                 foreground = 'A';
14317             } else if (r.foregroundServices) {
14318                 foreground = 'S';
14319             } else {
14320                 foreground = ' ';
14321             }
14322             String procState = ProcessList.makeProcStateString(r.curProcState);
14323             pw.print(prefix);
14324             pw.print(r.persistent ? persistentLabel : normalLabel);
14325             pw.print(" #");
14326             int num = (origList.size()-1)-list.get(i).second;
14327             if (num < 10) pw.print(' ');
14328             pw.print(num);
14329             pw.print(": ");
14330             pw.print(oomAdj);
14331             pw.print(' ');
14332             pw.print(schedGroup);
14333             pw.print('/');
14334             pw.print(foreground);
14335             pw.print('/');
14336             pw.print(procState);
14337             pw.print(" trm:");
14338             if (r.trimMemoryLevel < 10) pw.print(' ');
14339             pw.print(r.trimMemoryLevel);
14340             pw.print(' ');
14341             pw.print(r.toShortString());
14342             pw.print(" (");
14343             pw.print(r.adjType);
14344             pw.println(')');
14345             if (r.adjSource != null || r.adjTarget != null) {
14346                 pw.print(prefix);
14347                 pw.print("    ");
14348                 if (r.adjTarget instanceof ComponentName) {
14349                     pw.print(((ComponentName)r.adjTarget).flattenToShortString());
14350                 } else if (r.adjTarget != null) {
14351                     pw.print(r.adjTarget.toString());
14352                 } else {
14353                     pw.print("{null}");
14354                 }
14355                 pw.print("<=");
14356                 if (r.adjSource instanceof ProcessRecord) {
14357                     pw.print("Proc{");
14358                     pw.print(((ProcessRecord)r.adjSource).toShortString());
14359                     pw.println("}");
14360                 } else if (r.adjSource != null) {
14361                     pw.println(r.adjSource.toString());
14362                 } else {
14363                     pw.println("{null}");
14364                 }
14365             }
14366             if (inclDetails) {
14367                 pw.print(prefix);
14368                 pw.print("    ");
14369                 pw.print("oom: max="); pw.print(r.maxAdj);
14370                 pw.print(" curRaw="); pw.print(r.curRawAdj);
14371                 pw.print(" setRaw="); pw.print(r.setRawAdj);
14372                 pw.print(" cur="); pw.print(r.curAdj);
14373                 pw.print(" set="); pw.println(r.setAdj);
14374                 pw.print(prefix);
14375                 pw.print("    ");
14376                 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
14377                 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
14378                 pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
14379                 pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
14380                 pw.println();
14381                 pw.print(prefix);
14382                 pw.print("    ");
14383                 pw.print("cached="); pw.print(r.cached);
14384                 pw.print(" empty="); pw.print(r.empty);
14385                 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
14386
14387                 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
14388                     if (r.lastWakeTime != 0) {
14389                         long wtime;
14390                         BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
14391                         synchronized (stats) {
14392                             wtime = stats.getProcessWakeTime(r.info.uid,
14393                                     r.pid, curRealtime);
14394                         }
14395                         long timeUsed = wtime - r.lastWakeTime;
14396                         pw.print(prefix);
14397                         pw.print("    ");
14398                         pw.print("keep awake over ");
14399                         TimeUtils.formatDuration(realtimeSince, pw);
14400                         pw.print(" used ");
14401                         TimeUtils.formatDuration(timeUsed, pw);
14402                         pw.print(" (");
14403                         pw.print((timeUsed*100)/realtimeSince);
14404                         pw.println("%)");
14405                     }
14406                     if (r.lastCpuTime != 0) {
14407                         long timeUsed = r.curCpuTime - r.lastCpuTime;
14408                         pw.print(prefix);
14409                         pw.print("    ");
14410                         pw.print("run cpu over ");
14411                         TimeUtils.formatDuration(uptimeSince, pw);
14412                         pw.print(" used ");
14413                         TimeUtils.formatDuration(timeUsed, pw);
14414                         pw.print(" (");
14415                         pw.print((timeUsed*100)/uptimeSince);
14416                         pw.println("%)");
14417                     }
14418                 }
14419             }
14420         }
14421         return true;
14422     }
14423
14424     ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
14425             String[] args) {
14426         ArrayList<ProcessRecord> procs;
14427         synchronized (this) {
14428             if (args != null && args.length > start
14429                     && args[start].charAt(0) != '-') {
14430                 procs = new ArrayList<ProcessRecord>();
14431                 int pid = -1;
14432                 try {
14433                     pid = Integer.parseInt(args[start]);
14434                 } catch (NumberFormatException e) {
14435                 }
14436                 for (int i=mLruProcesses.size()-1; i>=0; i--) {
14437                     ProcessRecord proc = mLruProcesses.get(i);
14438                     if (proc.pid == pid) {
14439                         procs.add(proc);
14440                     } else if (allPkgs && proc.pkgList != null
14441                             && proc.pkgList.containsKey(args[start])) {
14442                         procs.add(proc);
14443                     } else if (proc.processName.equals(args[start])) {
14444                         procs.add(proc);
14445                     }
14446                 }
14447                 if (procs.size() <= 0) {
14448                     return null;
14449                 }
14450             } else {
14451                 procs = new ArrayList<ProcessRecord>(mLruProcesses);
14452             }
14453         }
14454         return procs;
14455     }
14456
14457     final void dumpGraphicsHardwareUsage(FileDescriptor fd,
14458             PrintWriter pw, String[] args) {
14459         ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
14460         if (procs == null) {
14461             pw.println("No process found for: " + args[0]);
14462             return;
14463         }
14464
14465         long uptime = SystemClock.uptimeMillis();
14466         long realtime = SystemClock.elapsedRealtime();
14467         pw.println("Applications Graphics Acceleration Info:");
14468         pw.println("Uptime: " + uptime + " Realtime: " + realtime);
14469
14470         for (int i = procs.size() - 1 ; i >= 0 ; i--) {
14471             ProcessRecord r = procs.get(i);
14472             if (r.thread != null) {
14473                 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
14474                 pw.flush();
14475                 try {
14476                     TransferPipe tp = new TransferPipe();
14477                     try {
14478                         r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
14479                         tp.go(fd);
14480                     } finally {
14481                         tp.kill();
14482                     }
14483                 } catch (IOException e) {
14484                     pw.println("Failure while dumping the app: " + r);
14485                     pw.flush();
14486                 } catch (RemoteException e) {
14487                     pw.println("Got a RemoteException while dumping the app " + r);
14488                     pw.flush();
14489                 }
14490             }
14491         }
14492     }
14493
14494     final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
14495         ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
14496         if (procs == null) {
14497             pw.println("No process found for: " + args[0]);
14498             return;
14499         }
14500
14501         pw.println("Applications Database Info:");
14502
14503         for (int i = procs.size() - 1 ; i >= 0 ; i--) {
14504             ProcessRecord r = procs.get(i);
14505             if (r.thread != null) {
14506                 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
14507                 pw.flush();
14508                 try {
14509                     TransferPipe tp = new TransferPipe();
14510                     try {
14511                         r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
14512                         tp.go(fd);
14513                     } finally {
14514                         tp.kill();
14515                     }
14516                 } catch (IOException e) {
14517                     pw.println("Failure while dumping the app: " + r);
14518                     pw.flush();
14519                 } catch (RemoteException e) {
14520                     pw.println("Got a RemoteException while dumping the app " + r);
14521                     pw.flush();
14522                 }
14523             }
14524         }
14525     }
14526
14527     final static class MemItem {
14528         final boolean isProc;
14529         final String label;
14530         final String shortLabel;
14531         final long pss;
14532         final int id;
14533         final boolean hasActivities;
14534         ArrayList<MemItem> subitems;
14535
14536         public MemItem(String _label, String _shortLabel, long _pss, int _id,
14537                 boolean _hasActivities) {
14538             isProc = true;
14539             label = _label;
14540             shortLabel = _shortLabel;
14541             pss = _pss;
14542             id = _id;
14543             hasActivities = _hasActivities;
14544         }
14545
14546         public MemItem(String _label, String _shortLabel, long _pss, int _id) {
14547             isProc = false;
14548             label = _label;
14549             shortLabel = _shortLabel;
14550             pss = _pss;
14551             id = _id;
14552             hasActivities = false;
14553         }
14554     }
14555
14556     static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
14557             ArrayList<MemItem> items, boolean sort, boolean isCompact) {
14558         if (sort && !isCompact) {
14559             Collections.sort(items, new Comparator<MemItem>() {
14560                 @Override
14561                 public int compare(MemItem lhs, MemItem rhs) {
14562                     if (lhs.pss < rhs.pss) {
14563                         return 1;
14564                     } else if (lhs.pss > rhs.pss) {
14565                         return -1;
14566                     }
14567                     return 0;
14568                 }
14569             });
14570         }
14571
14572         for (int i=0; i<items.size(); i++) {
14573             MemItem mi = items.get(i);
14574             if (!isCompact) {
14575                 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
14576             } else if (mi.isProc) {
14577                 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
14578                 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
14579                 pw.println(mi.hasActivities ? ",a" : ",e");
14580             } else {
14581                 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
14582                 pw.println(mi.pss);
14583             }
14584             if (mi.subitems != null) {
14585                 dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
14586                         true, isCompact);
14587             }
14588         }
14589     }
14590
14591     // These are in KB.
14592     static final long[] DUMP_MEM_BUCKETS = new long[] {
14593         5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
14594         120*1024, 160*1024, 200*1024,
14595         250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
14596         1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
14597     };
14598
14599     static final void appendMemBucket(StringBuilder out, long memKB, String label,
14600             boolean stackLike) {
14601         int start = label.lastIndexOf('.');
14602         if (start >= 0) start++;
14603         else start = 0;
14604         int end = label.length();
14605         for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
14606             if (DUMP_MEM_BUCKETS[i] >= memKB) {
14607                 long bucket = DUMP_MEM_BUCKETS[i]/1024;
14608                 out.append(bucket);
14609                 out.append(stackLike ? "MB." : "MB ");
14610                 out.append(label, start, end);
14611                 return;
14612             }
14613         }
14614         out.append(memKB/1024);
14615         out.append(stackLike ? "MB." : "MB ");
14616         out.append(label, start, end);
14617     }
14618
14619     static final int[] DUMP_MEM_OOM_ADJ = new int[] {
14620             ProcessList.NATIVE_ADJ,
14621             ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
14622             ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
14623             ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
14624             ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
14625             ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
14626             ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
14627     };
14628     static final String[] DUMP_MEM_OOM_LABEL = new String[] {
14629             "Native",
14630             "System", "Persistent", "Persistent Service", "Foreground",
14631             "Visible", "Perceptible",
14632             "Heavy Weight", "Backup",
14633             "A Services", "Home",
14634             "Previous", "B Services", "Cached"
14635     };
14636     static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
14637             "native",
14638             "sys", "pers", "persvc", "fore",
14639             "vis", "percept",
14640             "heavy", "backup",
14641             "servicea", "home",
14642             "prev", "serviceb", "cached"
14643     };
14644
14645     private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
14646             long realtime, boolean isCheckinRequest, boolean isCompact) {
14647         if (isCheckinRequest || isCompact) {
14648             // short checkin version
14649             pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
14650         } else {
14651             pw.println("Applications Memory Usage (kB):");
14652             pw.println("Uptime: " + uptime + " Realtime: " + realtime);
14653         }
14654     }
14655
14656     private static final int KSM_SHARED = 0;
14657     private static final int KSM_SHARING = 1;
14658     private static final int KSM_UNSHARED = 2;
14659     private static final int KSM_VOLATILE = 3;
14660
14661     private final long[] getKsmInfo() {
14662         long[] longOut = new long[4];
14663         final int[] SINGLE_LONG_FORMAT = new int[] {
14664             Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
14665         };
14666         long[] longTmp = new long[1];
14667         Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
14668                 SINGLE_LONG_FORMAT, null, longTmp, null);
14669         longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14670         longTmp[0] = 0;
14671         Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
14672                 SINGLE_LONG_FORMAT, null, longTmp, null);
14673         longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14674         longTmp[0] = 0;
14675         Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
14676                 SINGLE_LONG_FORMAT, null, longTmp, null);
14677         longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14678         longTmp[0] = 0;
14679         Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
14680                 SINGLE_LONG_FORMAT, null, longTmp, null);
14681         longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14682         return longOut;
14683     }
14684
14685     final void dumpApplicationMemoryUsage(FileDescriptor fd,
14686             PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
14687         boolean dumpDetails = false;
14688         boolean dumpFullDetails = false;
14689         boolean dumpDalvik = false;
14690         boolean dumpSummaryOnly = false;
14691         boolean oomOnly = false;
14692         boolean isCompact = false;
14693         boolean localOnly = false;
14694         boolean packages = false;
14695
14696         int opti = 0;
14697         while (opti < args.length) {
14698             String opt = args[opti];
14699             if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
14700                 break;
14701             }
14702             opti++;
14703             if ("-a".equals(opt)) {
14704                 dumpDetails = true;
14705                 dumpFullDetails = true;
14706                 dumpDalvik = true;
14707             } else if ("-d".equals(opt)) {
14708                 dumpDalvik = true;
14709             } else if ("-c".equals(opt)) {
14710                 isCompact = true;
14711             } else if ("-s".equals(opt)) {
14712                 dumpDetails = true;
14713                 dumpSummaryOnly = true;
14714             } else if ("--oom".equals(opt)) {
14715                 oomOnly = true;
14716             } else if ("--local".equals(opt)) {
14717                 localOnly = true;
14718             } else if ("--package".equals(opt)) {
14719                 packages = true;
14720             } else if ("-h".equals(opt)) {
14721                 pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
14722                 pw.println("  -a: include all available information for each process.");
14723                 pw.println("  -d: include dalvik details.");
14724                 pw.println("  -c: dump in a compact machine-parseable representation.");
14725                 pw.println("  -s: dump only summary of application memory usage.");
14726                 pw.println("  --oom: only show processes organized by oom adj.");
14727                 pw.println("  --local: only collect details locally, don't call process.");
14728                 pw.println("  --package: interpret process arg as package, dumping all");
14729                 pw.println("             processes that have loaded that package.");
14730                 pw.println("If [process] is specified it can be the name or ");
14731                 pw.println("pid of a specific process to dump.");
14732                 return;
14733             } else {
14734                 pw.println("Unknown argument: " + opt + "; use -h for help");
14735             }
14736         }
14737
14738         final boolean isCheckinRequest = scanArgs(args, "--checkin");
14739         long uptime = SystemClock.uptimeMillis();
14740         long realtime = SystemClock.elapsedRealtime();
14741         final long[] tmpLong = new long[1];
14742
14743         ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
14744         if (procs == null) {
14745             // No Java processes.  Maybe they want to print a native process.
14746             if (args != null && args.length > opti
14747                     && args[opti].charAt(0) != '-') {
14748                 ArrayList<ProcessCpuTracker.Stats> nativeProcs
14749                         = new ArrayList<ProcessCpuTracker.Stats>();
14750                 updateCpuStatsNow();
14751                 int findPid = -1;
14752                 try {
14753                     findPid = Integer.parseInt(args[opti]);
14754                 } catch (NumberFormatException e) {
14755                 }
14756                 synchronized (mProcessCpuTracker) {
14757                     final int N = mProcessCpuTracker.countStats();
14758                     for (int i=0; i<N; i++) {
14759                         ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14760                         if (st.pid == findPid || (st.baseName != null
14761                                 && st.baseName.equals(args[opti]))) {
14762                             nativeProcs.add(st);
14763                         }
14764                     }
14765                 }
14766                 if (nativeProcs.size() > 0) {
14767                     dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
14768                             isCompact);
14769                     Debug.MemoryInfo mi = null;
14770                     for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
14771                         final ProcessCpuTracker.Stats r = nativeProcs.get(i);
14772                         final int pid = r.pid;
14773                         if (!isCheckinRequest && dumpDetails) {
14774                             pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
14775                         }
14776                         if (mi == null) {
14777                             mi = new Debug.MemoryInfo();
14778                         }
14779                         if (dumpDetails || (!brief && !oomOnly)) {
14780                             Debug.getMemoryInfo(pid, mi);
14781                         } else {
14782                             mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
14783                             mi.dalvikPrivateDirty = (int)tmpLong[0];
14784                         }
14785                         ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
14786                                 dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
14787                         if (isCheckinRequest) {
14788                             pw.println();
14789                         }
14790                     }
14791                     return;
14792                 }
14793             }
14794             pw.println("No process found for: " + args[opti]);
14795             return;
14796         }
14797
14798         if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
14799             dumpDetails = true;
14800         }
14801
14802         dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
14803
14804         String[] innerArgs = new String[args.length-opti];
14805         System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
14806
14807         ArrayList<MemItem> procMems = new ArrayList<MemItem>();
14808         final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
14809         long nativePss = 0;
14810         long dalvikPss = 0;
14811         long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
14812                 EmptyArray.LONG;
14813         long otherPss = 0;
14814         long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
14815
14816         long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
14817         ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
14818                 new ArrayList[DUMP_MEM_OOM_LABEL.length];
14819
14820         long totalPss = 0;
14821         long cachedPss = 0;
14822
14823         Debug.MemoryInfo mi = null;
14824         for (int i = procs.size() - 1 ; i >= 0 ; i--) {
14825             final ProcessRecord r = procs.get(i);
14826             final IApplicationThread thread;
14827             final int pid;
14828             final int oomAdj;
14829             final boolean hasActivities;
14830             synchronized (this) {
14831                 thread = r.thread;
14832                 pid = r.pid;
14833                 oomAdj = r.getSetAdjWithServices();
14834                 hasActivities = r.activities.size() > 0;
14835             }
14836             if (thread != null) {
14837                 if (!isCheckinRequest && dumpDetails) {
14838                     pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
14839                 }
14840                 if (mi == null) {
14841                     mi = new Debug.MemoryInfo();
14842                 }
14843                 if (dumpDetails || (!brief && !oomOnly)) {
14844                     Debug.getMemoryInfo(pid, mi);
14845                 } else {
14846                     mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
14847                     mi.dalvikPrivateDirty = (int)tmpLong[0];
14848                 }
14849                 if (dumpDetails) {
14850                     if (localOnly) {
14851                         ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
14852                                 dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
14853                         if (isCheckinRequest) {
14854                             pw.println();
14855                         }
14856                     } else {
14857                         try {
14858                             pw.flush();
14859                             thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
14860                                     dumpDalvik, dumpSummaryOnly, innerArgs);
14861                         } catch (RemoteException e) {
14862                             if (!isCheckinRequest) {
14863                                 pw.println("Got RemoteException!");
14864                                 pw.flush();
14865                             }
14866                         }
14867                     }
14868                 }
14869
14870                 final long myTotalPss = mi.getTotalPss();
14871                 final long myTotalUss = mi.getTotalUss();
14872
14873                 synchronized (this) {
14874                     if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
14875                         // Record this for posterity if the process has been stable.
14876                         r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
14877                     }
14878                 }
14879
14880                 if (!isCheckinRequest && mi != null) {
14881                     totalPss += myTotalPss;
14882                     MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
14883                             (hasActivities ? " / activities)" : ")"),
14884                             r.processName, myTotalPss, pid, hasActivities);
14885                     procMems.add(pssItem);
14886                     procMemsMap.put(pid, pssItem);
14887
14888                     nativePss += mi.nativePss;
14889                     dalvikPss += mi.dalvikPss;
14890                     for (int j=0; j<dalvikSubitemPss.length; j++) {
14891                         dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
14892                     }
14893                     otherPss += mi.otherPss;
14894                     for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14895                         long mem = mi.getOtherPss(j);
14896                         miscPss[j] += mem;
14897                         otherPss -= mem;
14898                     }
14899
14900                     if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
14901                         cachedPss += myTotalPss;
14902                     }
14903
14904                     for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
14905                         if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
14906                                 || oomIndex == (oomPss.length-1)) {
14907                             oomPss[oomIndex] += myTotalPss;
14908                             if (oomProcs[oomIndex] == null) {
14909                                 oomProcs[oomIndex] = new ArrayList<MemItem>();
14910                             }
14911                             oomProcs[oomIndex].add(pssItem);
14912                             break;
14913                         }
14914                     }
14915                 }
14916             }
14917         }
14918
14919         long nativeProcTotalPss = 0;
14920
14921         if (!isCheckinRequest && procs.size() > 1 && !packages) {
14922             // If we are showing aggregations, also look for native processes to
14923             // include so that our aggregations are more accurate.
14924             updateCpuStatsNow();
14925             mi = null;
14926             synchronized (mProcessCpuTracker) {
14927                 final int N = mProcessCpuTracker.countStats();
14928                 for (int i=0; i<N; i++) {
14929                     ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14930                     if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
14931                         if (mi == null) {
14932                             mi = new Debug.MemoryInfo();
14933                         }
14934                         if (!brief && !oomOnly) {
14935                             Debug.getMemoryInfo(st.pid, mi);
14936                         } else {
14937                             mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
14938                             mi.nativePrivateDirty = (int)tmpLong[0];
14939                         }
14940
14941                         final long myTotalPss = mi.getTotalPss();
14942                         totalPss += myTotalPss;
14943                         nativeProcTotalPss += myTotalPss;
14944
14945                         MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
14946                                 st.name, myTotalPss, st.pid, false);
14947                         procMems.add(pssItem);
14948
14949                         nativePss += mi.nativePss;
14950                         dalvikPss += mi.dalvikPss;
14951                         for (int j=0; j<dalvikSubitemPss.length; j++) {
14952                             dalvikSubitemPss[j] += mi.getOtherPss(
14953                                     Debug.MemoryInfo.NUM_OTHER_STATS + j);
14954                         }
14955                         otherPss += mi.otherPss;
14956                         for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14957                             long mem = mi.getOtherPss(j);
14958                             miscPss[j] += mem;
14959                             otherPss -= mem;
14960                         }
14961                         oomPss[0] += myTotalPss;
14962                         if (oomProcs[0] == null) {
14963                             oomProcs[0] = new ArrayList<MemItem>();
14964                         }
14965                         oomProcs[0].add(pssItem);
14966                     }
14967                 }
14968             }
14969
14970             ArrayList<MemItem> catMems = new ArrayList<MemItem>();
14971
14972             catMems.add(new MemItem("Native", "Native", nativePss, -1));
14973             final MemItem dalvikItem = new MemItem("Dalvik", "Dalvik", dalvikPss, -2);
14974             if (dalvikSubitemPss.length > 0) {
14975                 dalvikItem.subitems = new ArrayList<MemItem>();
14976                 for (int j=0; j<dalvikSubitemPss.length; j++) {
14977                     final String name = Debug.MemoryInfo.getOtherLabel(
14978                             Debug.MemoryInfo.NUM_OTHER_STATS + j);
14979                     dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j], j));
14980                 }
14981             }
14982             catMems.add(dalvikItem);
14983             catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
14984             for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14985                 String label = Debug.MemoryInfo.getOtherLabel(j);
14986                 catMems.add(new MemItem(label, label, miscPss[j], j));
14987             }
14988
14989             ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
14990             for (int j=0; j<oomPss.length; j++) {
14991                 if (oomPss[j] != 0) {
14992                     String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
14993                             : DUMP_MEM_OOM_LABEL[j];
14994                     MemItem item = new MemItem(label, label, oomPss[j],
14995                             DUMP_MEM_OOM_ADJ[j]);
14996                     item.subitems = oomProcs[j];
14997                     oomMems.add(item);
14998                 }
14999             }
15000
15001             if (!brief && !oomOnly && !isCompact) {
15002                 pw.println();
15003                 pw.println("Total PSS by process:");
15004                 dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
15005                 pw.println();
15006             }
15007             if (!isCompact) {
15008                 pw.println("Total PSS by OOM adjustment:");
15009             }
15010             dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
15011             if (!brief && !oomOnly) {
15012                 PrintWriter out = categoryPw != null ? categoryPw : pw;
15013                 if (!isCompact) {
15014                     out.println();
15015                     out.println("Total PSS by category:");
15016                 }
15017                 dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
15018             }
15019             if (!isCompact) {
15020                 pw.println();
15021             }
15022             MemInfoReader memInfo = new MemInfoReader();
15023             memInfo.readMemInfo();
15024             if (nativeProcTotalPss > 0) {
15025                 synchronized (this) {
15026                     final long cachedKb = memInfo.getCachedSizeKb();
15027                     final long freeKb = memInfo.getFreeSizeKb();
15028                     final long zramKb = memInfo.getZramTotalSizeKb();
15029                     final long kernelKb = memInfo.getKernelUsedSizeKb();
15030                     EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
15031                             kernelKb*1024, nativeProcTotalPss*1024);
15032                     mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
15033                             nativeProcTotalPss);
15034                 }
15035             }
15036             if (!brief) {
15037                 if (!isCompact) {
15038                     pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
15039                     pw.print(" kB (status ");
15040                     switch (mLastMemoryLevel) {
15041                         case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
15042                             pw.println("normal)");
15043                             break;
15044                         case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
15045                             pw.println("moderate)");
15046                             break;
15047                         case ProcessStats.ADJ_MEM_FACTOR_LOW:
15048                             pw.println("low)");
15049                             break;
15050                         case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
15051                             pw.println("critical)");
15052                             break;
15053                         default:
15054                             pw.print(mLastMemoryLevel);
15055                             pw.println(")");
15056                             break;
15057                     }
15058                     pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
15059                             + memInfo.getFreeSizeKb()); pw.print(" kB (");
15060                             pw.print(cachedPss); pw.print(" cached pss + ");
15061                             pw.print(memInfo.getCachedSizeKb()); pw.print(" cached kernel + ");
15062                             pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
15063                 } else {
15064                     pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
15065                     pw.print(cachedPss + memInfo.getCachedSizeKb()
15066                             + memInfo.getFreeSizeKb()); pw.print(",");
15067                     pw.println(totalPss - cachedPss);
15068                 }
15069             }
15070             if (!isCompact) {
15071                 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
15072                         + memInfo.getKernelUsedSizeKb()); pw.print(" kB (");
15073                         pw.print(totalPss - cachedPss); pw.print(" used pss + ");
15074                         pw.print(memInfo.getKernelUsedSizeKb()); pw.print(" kernel)\n");
15075                 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
15076                         - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
15077                         - memInfo.getKernelUsedSizeKb()); pw.println(" kB");
15078             }
15079             if (!brief) {
15080                 if (memInfo.getZramTotalSizeKb() != 0) {
15081                     if (!isCompact) {
15082                         pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
15083                                 pw.print(" kB physical used for ");
15084                                 pw.print(memInfo.getSwapTotalSizeKb()
15085                                         - memInfo.getSwapFreeSizeKb());
15086                                 pw.print(" kB in swap (");
15087                                 pw.print(memInfo.getSwapTotalSizeKb());
15088                                 pw.println(" kB total swap)");
15089                     } else {
15090                         pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
15091                                 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
15092                                 pw.println(memInfo.getSwapFreeSizeKb());
15093                     }
15094                 }
15095                 final long[] ksm = getKsmInfo();
15096                 if (!isCompact) {
15097                     if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
15098                             || ksm[KSM_VOLATILE] != 0) {
15099                         pw.print("      KSM: "); pw.print(ksm[KSM_SHARING]);
15100                                 pw.print(" kB saved from shared ");
15101                                 pw.print(ksm[KSM_SHARED]); pw.println(" kB");
15102                         pw.print("           "); pw.print(ksm[KSM_UNSHARED]);
15103                                 pw.print(" kB unshared; ");
15104                                 pw.print(ksm[KSM_VOLATILE]); pw.println(" kB volatile");
15105                     }
15106                     pw.print("   Tuning: ");
15107                     pw.print(ActivityManager.staticGetMemoryClass());
15108                     pw.print(" (large ");
15109                     pw.print(ActivityManager.staticGetLargeMemoryClass());
15110                     pw.print("), oom ");
15111                     pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
15112                     pw.print(" kB");
15113                     pw.print(", restore limit ");
15114                     pw.print(mProcessList.getCachedRestoreThresholdKb());
15115                     pw.print(" kB");
15116                     if (ActivityManager.isLowRamDeviceStatic()) {
15117                         pw.print(" (low-ram)");
15118                     }
15119                     if (ActivityManager.isHighEndGfx()) {
15120                         pw.print(" (high-end-gfx)");
15121                     }
15122                     pw.println();
15123                 } else {
15124                     pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
15125                     pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
15126                     pw.print(","); pw.println(ksm[KSM_VOLATILE]);
15127                     pw.print("tuning,");
15128                     pw.print(ActivityManager.staticGetMemoryClass());
15129                     pw.print(',');
15130                     pw.print(ActivityManager.staticGetLargeMemoryClass());
15131                     pw.print(',');
15132                     pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
15133                     if (ActivityManager.isLowRamDeviceStatic()) {
15134                         pw.print(",low-ram");
15135                     }
15136                     if (ActivityManager.isHighEndGfx()) {
15137                         pw.print(",high-end-gfx");
15138                     }
15139                     pw.println();
15140                 }
15141             }
15142         }
15143     }
15144
15145     private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
15146             long memtrack, String name) {
15147         sb.append("  ");
15148         sb.append(ProcessList.makeOomAdjString(oomAdj));
15149         sb.append(' ');
15150         sb.append(ProcessList.makeProcStateString(procState));
15151         sb.append(' ');
15152         ProcessList.appendRamKb(sb, pss);
15153         sb.append(" kB: ");
15154         sb.append(name);
15155         if (memtrack > 0) {
15156             sb.append(" (");
15157             sb.append(memtrack);
15158             sb.append(" kB memtrack)");
15159         }
15160     }
15161
15162     private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
15163         appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
15164         sb.append(" (pid ");
15165         sb.append(mi.pid);
15166         sb.append(") ");
15167         sb.append(mi.adjType);
15168         sb.append('\n');
15169         if (mi.adjReason != null) {
15170             sb.append("                      ");
15171             sb.append(mi.adjReason);
15172             sb.append('\n');
15173         }
15174     }
15175
15176     void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
15177         final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
15178         for (int i=0, N=memInfos.size(); i<N; i++) {
15179             ProcessMemInfo mi = memInfos.get(i);
15180             infoMap.put(mi.pid, mi);
15181         }
15182         updateCpuStatsNow();
15183         long[] memtrackTmp = new long[1];
15184         synchronized (mProcessCpuTracker) {
15185             final int N = mProcessCpuTracker.countStats();
15186             for (int i=0; i<N; i++) {
15187                 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15188                 if (st.vsize > 0) {
15189                     long pss = Debug.getPss(st.pid, null, memtrackTmp);
15190                     if (pss > 0) {
15191                         if (infoMap.indexOfKey(st.pid) < 0) {
15192                             ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
15193                                     ProcessList.NATIVE_ADJ, -1, "native", null);
15194                             mi.pss = pss;
15195                             mi.memtrack = memtrackTmp[0];
15196                             memInfos.add(mi);
15197                         }
15198                     }
15199                 }
15200             }
15201         }
15202
15203         long totalPss = 0;
15204         long totalMemtrack = 0;
15205         for (int i=0, N=memInfos.size(); i<N; i++) {
15206             ProcessMemInfo mi = memInfos.get(i);
15207             if (mi.pss == 0) {
15208                 mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
15209                 mi.memtrack = memtrackTmp[0];
15210             }
15211             totalPss += mi.pss;
15212             totalMemtrack += mi.memtrack;
15213         }
15214         Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
15215             @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
15216                 if (lhs.oomAdj != rhs.oomAdj) {
15217                     return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
15218                 }
15219                 if (lhs.pss != rhs.pss) {
15220                     return lhs.pss < rhs.pss ? 1 : -1;
15221                 }
15222                 return 0;
15223             }
15224         });
15225
15226         StringBuilder tag = new StringBuilder(128);
15227         StringBuilder stack = new StringBuilder(128);
15228         tag.append("Low on memory -- ");
15229         appendMemBucket(tag, totalPss, "total", false);
15230         appendMemBucket(stack, totalPss, "total", true);
15231
15232         StringBuilder fullNativeBuilder = new StringBuilder(1024);
15233         StringBuilder shortNativeBuilder = new StringBuilder(1024);
15234         StringBuilder fullJavaBuilder = new StringBuilder(1024);
15235
15236         boolean firstLine = true;
15237         int lastOomAdj = Integer.MIN_VALUE;
15238         long extraNativeRam = 0;
15239         long extraNativeMemtrack = 0;
15240         long cachedPss = 0;
15241         for (int i=0, N=memInfos.size(); i<N; i++) {
15242             ProcessMemInfo mi = memInfos.get(i);
15243
15244             if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
15245                 cachedPss += mi.pss;
15246             }
15247
15248             if (mi.oomAdj != ProcessList.NATIVE_ADJ
15249                     && (mi.oomAdj < ProcessList.SERVICE_ADJ
15250                             || mi.oomAdj == ProcessList.HOME_APP_ADJ
15251                             || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
15252                 if (lastOomAdj != mi.oomAdj) {
15253                     lastOomAdj = mi.oomAdj;
15254                     if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15255                         tag.append(" / ");
15256                     }
15257                     if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
15258                         if (firstLine) {
15259                             stack.append(":");
15260                             firstLine = false;
15261                         }
15262                         stack.append("\n\t at ");
15263                     } else {
15264                         stack.append("$");
15265                     }
15266                 } else {
15267                     tag.append(" ");
15268                     stack.append("$");
15269                 }
15270                 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15271                     appendMemBucket(tag, mi.pss, mi.name, false);
15272                 }
15273                 appendMemBucket(stack, mi.pss, mi.name, true);
15274                 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
15275                         && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
15276                     stack.append("(");
15277                     for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
15278                         if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
15279                             stack.append(DUMP_MEM_OOM_LABEL[k]);
15280                             stack.append(":");
15281                             stack.append(DUMP_MEM_OOM_ADJ[k]);
15282                         }
15283                     }
15284                     stack.append(")");
15285                 }
15286             }
15287
15288             appendMemInfo(fullNativeBuilder, mi);
15289             if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
15290                 // The short form only has native processes that are >= 512K.
15291                 if (mi.pss >= 512) {
15292                     appendMemInfo(shortNativeBuilder, mi);
15293                 } else {
15294                     extraNativeRam += mi.pss;
15295                     extraNativeMemtrack += mi.memtrack;
15296                 }
15297             } else {
15298                 // Short form has all other details, but if we have collected RAM
15299                 // from smaller native processes let's dump a summary of that.
15300                 if (extraNativeRam > 0) {
15301                     appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
15302                             -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
15303                     shortNativeBuilder.append('\n');
15304                     extraNativeRam = 0;
15305                 }
15306                 appendMemInfo(fullJavaBuilder, mi);
15307             }
15308         }
15309
15310         fullJavaBuilder.append("           ");
15311         ProcessList.appendRamKb(fullJavaBuilder, totalPss);
15312         fullJavaBuilder.append(" kB: TOTAL");
15313         if (totalMemtrack > 0) {
15314             fullJavaBuilder.append(" (");
15315             fullJavaBuilder.append(totalMemtrack);
15316             fullJavaBuilder.append(" kB memtrack)");
15317         } else {
15318         }
15319         fullJavaBuilder.append("\n");
15320
15321         MemInfoReader memInfo = new MemInfoReader();
15322         memInfo.readMemInfo();
15323         final long[] infos = memInfo.getRawInfo();
15324
15325         StringBuilder memInfoBuilder = new StringBuilder(1024);
15326         Debug.getMemInfo(infos);
15327         memInfoBuilder.append("  MemInfo: ");
15328         memInfoBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
15329         memInfoBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
15330         memInfoBuilder.append(infos[Debug.MEMINFO_VM_ALLOC_USED]).append(" kB vm alloc, ");
15331         memInfoBuilder.append(infos[Debug.MEMINFO_PAGE_TABLES]).append(" kB page tables ");
15332         memInfoBuilder.append(infos[Debug.MEMINFO_KERNEL_STACK]).append(" kB kernel stack\n");
15333         memInfoBuilder.append("           ");
15334         memInfoBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
15335         memInfoBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
15336         memInfoBuilder.append(infos[Debug.MEMINFO_MAPPED]).append(" kB mapped, ");
15337         memInfoBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
15338         if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
15339             memInfoBuilder.append("  ZRAM: ");
15340             memInfoBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
15341             memInfoBuilder.append(" kB RAM, ");
15342             memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
15343             memInfoBuilder.append(" kB swap total, ");
15344             memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
15345             memInfoBuilder.append(" kB swap free\n");
15346         }
15347         final long[] ksm = getKsmInfo();
15348         if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
15349                 || ksm[KSM_VOLATILE] != 0) {
15350             memInfoBuilder.append("  KSM: "); memInfoBuilder.append(ksm[KSM_SHARING]);
15351             memInfoBuilder.append(" kB saved from shared ");
15352             memInfoBuilder.append(ksm[KSM_SHARED]); memInfoBuilder.append(" kB\n");
15353             memInfoBuilder.append("       "); memInfoBuilder.append(ksm[KSM_UNSHARED]);
15354             memInfoBuilder.append(" kB unshared; ");
15355             memInfoBuilder.append(ksm[KSM_VOLATILE]); memInfoBuilder.append(" kB volatile\n");
15356         }
15357         memInfoBuilder.append("  Free RAM: ");
15358         memInfoBuilder.append(cachedPss + memInfo.getCachedSizeKb()
15359                 + memInfo.getFreeSizeKb());
15360         memInfoBuilder.append(" kB\n");
15361         memInfoBuilder.append("  Used RAM: ");
15362         memInfoBuilder.append(totalPss - cachedPss + memInfo.getKernelUsedSizeKb());
15363         memInfoBuilder.append(" kB\n");
15364         memInfoBuilder.append("  Lost RAM: ");
15365         memInfoBuilder.append(memInfo.getTotalSizeKb()
15366                 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
15367                 - memInfo.getKernelUsedSizeKb());
15368         memInfoBuilder.append(" kB\n");
15369         Slog.i(TAG, "Low on memory:");
15370         Slog.i(TAG, shortNativeBuilder.toString());
15371         Slog.i(TAG, fullJavaBuilder.toString());
15372         Slog.i(TAG, memInfoBuilder.toString());
15373
15374         StringBuilder dropBuilder = new StringBuilder(1024);
15375         /*
15376         StringWriter oomSw = new StringWriter();
15377         PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
15378         StringWriter catSw = new StringWriter();
15379         PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
15380         String[] emptyArgs = new String[] { };
15381         dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
15382         oomPw.flush();
15383         String oomString = oomSw.toString();
15384         */
15385         dropBuilder.append("Low on memory:");
15386         dropBuilder.append(stack);
15387         dropBuilder.append('\n');
15388         dropBuilder.append(fullNativeBuilder);
15389         dropBuilder.append(fullJavaBuilder);
15390         dropBuilder.append('\n');
15391         dropBuilder.append(memInfoBuilder);
15392         dropBuilder.append('\n');
15393         /*
15394         dropBuilder.append(oomString);
15395         dropBuilder.append('\n');
15396         */
15397         StringWriter catSw = new StringWriter();
15398         synchronized (ActivityManagerService.this) {
15399             PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
15400             String[] emptyArgs = new String[] { };
15401             catPw.println();
15402             dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
15403             catPw.println();
15404             mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
15405                     false, false, null);
15406             catPw.println();
15407             dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
15408             catPw.flush();
15409         }
15410         dropBuilder.append(catSw.toString());
15411         addErrorToDropBox("lowmem", null, "system_server", null,
15412                 null, tag.toString(), dropBuilder.toString(), null, null);
15413         //Slog.i(TAG, "Sent to dropbox:");
15414         //Slog.i(TAG, dropBuilder.toString());
15415         synchronized (ActivityManagerService.this) {
15416             long now = SystemClock.uptimeMillis();
15417             if (mLastMemUsageReportTime < now) {
15418                 mLastMemUsageReportTime = now;
15419             }
15420         }
15421     }
15422
15423     /**
15424      * Searches array of arguments for the specified string
15425      * @param args array of argument strings
15426      * @param value value to search for
15427      * @return true if the value is contained in the array
15428      */
15429     private static boolean scanArgs(String[] args, String value) {
15430         if (args != null) {
15431             for (String arg : args) {
15432                 if (value.equals(arg)) {
15433                     return true;
15434                 }
15435             }
15436         }
15437         return false;
15438     }
15439
15440     private final boolean removeDyingProviderLocked(ProcessRecord proc,
15441             ContentProviderRecord cpr, boolean always) {
15442         final boolean inLaunching = mLaunchingProviders.contains(cpr);
15443
15444         if (!inLaunching || always) {
15445             synchronized (cpr) {
15446                 cpr.launchingApp = null;
15447                 cpr.notifyAll();
15448             }
15449             mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
15450             String names[] = cpr.info.authority.split(";");
15451             for (int j = 0; j < names.length; j++) {
15452                 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
15453             }
15454         }
15455
15456         for (int i = cpr.connections.size() - 1; i >= 0; i--) {
15457             ContentProviderConnection conn = cpr.connections.get(i);
15458             if (conn.waiting) {
15459                 // If this connection is waiting for the provider, then we don't
15460                 // need to mess with its process unless we are always removing
15461                 // or for some reason the provider is not currently launching.
15462                 if (inLaunching && !always) {
15463                     continue;
15464                 }
15465             }
15466             ProcessRecord capp = conn.client;
15467             conn.dead = true;
15468             if (conn.stableCount > 0) {
15469                 if (!capp.persistent && capp.thread != null
15470                         && capp.pid != 0
15471                         && capp.pid != MY_PID) {
15472                     capp.kill("depends on provider "
15473                             + cpr.name.flattenToShortString()
15474                             + " in dying proc " + (proc != null ? proc.processName : "??"), true);
15475                 }
15476             } else if (capp.thread != null && conn.provider.provider != null) {
15477                 try {
15478                     capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
15479                 } catch (RemoteException e) {
15480                 }
15481                 // In the protocol here, we don't expect the client to correctly
15482                 // clean up this connection, we'll just remove it.
15483                 cpr.connections.remove(i);
15484                 if (conn.client.conProviders.remove(conn)) {
15485                     stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
15486                 }
15487             }
15488         }
15489
15490         if (inLaunching && always) {
15491             mLaunchingProviders.remove(cpr);
15492         }
15493         return inLaunching;
15494     }
15495
15496     /**
15497      * Main code for cleaning up a process when it has gone away.  This is
15498      * called both as a result of the process dying, or directly when stopping
15499      * a process when running in single process mode.
15500      *
15501      * @return Returns true if the given process has been restarted, so the
15502      * app that was passed in must remain on the process lists.
15503      */
15504     private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
15505             boolean restarting, boolean allowRestart, int index) {
15506         if (index >= 0) {
15507             removeLruProcessLocked(app);
15508             ProcessList.remove(app.pid);
15509         }
15510
15511         mProcessesToGc.remove(app);
15512         mPendingPssProcesses.remove(app);
15513
15514         // Dismiss any open dialogs.
15515         if (app.crashDialog != null && !app.forceCrashReport) {
15516             app.crashDialog.dismiss();
15517             app.crashDialog = null;
15518         }
15519         if (app.anrDialog != null) {
15520             app.anrDialog.dismiss();
15521             app.anrDialog = null;
15522         }
15523         if (app.waitDialog != null) {
15524             app.waitDialog.dismiss();
15525             app.waitDialog = null;
15526         }
15527
15528         app.crashing = false;
15529         app.notResponding = false;
15530
15531         app.resetPackageList(mProcessStats);
15532         app.unlinkDeathRecipient();
15533         app.makeInactive(mProcessStats);
15534         app.waitingToKill = null;
15535         app.forcingToForeground = null;
15536         updateProcessForegroundLocked(app, false, false);
15537         app.foregroundActivities = false;
15538         app.hasShownUi = false;
15539         app.treatLikeActivity = false;
15540         app.hasAboveClient = false;
15541         app.hasClientActivities = false;
15542
15543         mServices.killServicesLocked(app, allowRestart);
15544
15545         boolean restart = false;
15546
15547         // Remove published content providers.
15548         for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
15549             ContentProviderRecord cpr = app.pubProviders.valueAt(i);
15550             final boolean always = app.bad || !allowRestart;
15551             boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
15552             if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
15553                 // We left the provider in the launching list, need to
15554                 // restart it.
15555                 restart = true;
15556             }
15557
15558             cpr.provider = null;
15559             cpr.proc = null;
15560         }
15561         app.pubProviders.clear();
15562
15563         // Take care of any launching providers waiting for this process.
15564         if (cleanupAppInLaunchingProvidersLocked(app, false)) {
15565             restart = true;
15566         }
15567
15568         // Unregister from connected content providers.
15569         if (!app.conProviders.isEmpty()) {
15570             for (int i = app.conProviders.size() - 1; i >= 0; i--) {
15571                 ContentProviderConnection conn = app.conProviders.get(i);
15572                 conn.provider.connections.remove(conn);
15573                 stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
15574                         conn.provider.name);
15575             }
15576             app.conProviders.clear();
15577         }
15578
15579         // At this point there may be remaining entries in mLaunchingProviders
15580         // where we were the only one waiting, so they are no longer of use.
15581         // Look for these and clean up if found.
15582         // XXX Commented out for now.  Trying to figure out a way to reproduce
15583         // the actual situation to identify what is actually going on.
15584         if (false) {
15585             for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
15586                 ContentProviderRecord cpr = mLaunchingProviders.get(i);
15587                 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
15588                     synchronized (cpr) {
15589                         cpr.launchingApp = null;
15590                         cpr.notifyAll();
15591                     }
15592                 }
15593             }
15594         }
15595
15596         skipCurrentReceiverLocked(app);
15597
15598         // Unregister any receivers.
15599         for (int i = app.receivers.size() - 1; i >= 0; i--) {
15600             removeReceiverLocked(app.receivers.valueAt(i));
15601         }
15602         app.receivers.clear();
15603
15604         // If the app is undergoing backup, tell the backup manager about it
15605         if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
15606             if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
15607                     + mBackupTarget.appInfo + " died during backup");
15608             try {
15609                 IBackupManager bm = IBackupManager.Stub.asInterface(
15610                         ServiceManager.getService(Context.BACKUP_SERVICE));
15611                 bm.agentDisconnected(app.info.packageName);
15612             } catch (RemoteException e) {
15613                 // can't happen; backup manager is local
15614             }
15615         }
15616
15617         for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
15618             ProcessChangeItem item = mPendingProcessChanges.get(i);
15619             if (item.pid == app.pid) {
15620                 mPendingProcessChanges.remove(i);
15621                 mAvailProcessChanges.add(item);
15622             }
15623         }
15624         mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
15625
15626         // If the caller is restarting this app, then leave it in its
15627         // current lists and let the caller take care of it.
15628         if (restarting) {
15629             return false;
15630         }
15631
15632         if (!app.persistent || app.isolated) {
15633             if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
15634                     "Removing non-persistent process during cleanup: " + app);
15635             removeProcessNameLocked(app.processName, app.uid);
15636             if (mHeavyWeightProcess == app) {
15637                 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
15638                         mHeavyWeightProcess.userId, 0));
15639                 mHeavyWeightProcess = null;
15640             }
15641         } else if (!app.removed) {
15642             // This app is persistent, so we need to keep its record around.
15643             // If it is not already on the pending app list, add it there
15644             // and start a new process for it.
15645             if (mPersistentStartingProcesses.indexOf(app) < 0) {
15646                 mPersistentStartingProcesses.add(app);
15647                 restart = true;
15648             }
15649         }
15650         if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
15651                 TAG_CLEANUP, "Clean-up removing on hold: " + app);
15652         mProcessesOnHold.remove(app);
15653
15654         if (app == mHomeProcess) {
15655             mHomeProcess = null;
15656         }
15657         if (app == mPreviousProcess) {
15658             mPreviousProcess = null;
15659         }
15660
15661         if (restart && !app.isolated) {
15662             // We have components that still need to be running in the
15663             // process, so re-launch it.
15664             if (index < 0) {
15665                 ProcessList.remove(app.pid);
15666             }
15667             addProcessNameLocked(app);
15668             startProcessLocked(app, "restart", app.processName);
15669             return true;
15670         } else if (app.pid > 0 && app.pid != MY_PID) {
15671             // Goodbye!
15672             boolean removed;
15673             synchronized (mPidsSelfLocked) {
15674                 mPidsSelfLocked.remove(app.pid);
15675                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
15676             }
15677             mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
15678             if (app.isolated) {
15679                 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
15680             }
15681             app.setPid(0);
15682         }
15683         return false;
15684     }
15685
15686     boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
15687         for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
15688             ContentProviderRecord cpr = mLaunchingProviders.get(i);
15689             if (cpr.launchingApp == app) {
15690                 return true;
15691             }
15692         }
15693         return false;
15694     }
15695
15696     boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
15697         // Look through the content providers we are waiting to have launched,
15698         // and if any run in this process then either schedule a restart of
15699         // the process or kill the client waiting for it if this process has
15700         // gone bad.
15701         boolean restart = false;
15702         for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
15703             ContentProviderRecord cpr = mLaunchingProviders.get(i);
15704             if (cpr.launchingApp == app) {
15705                 if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
15706                     restart = true;
15707                 } else {
15708                     removeDyingProviderLocked(app, cpr, true);
15709                 }
15710             }
15711         }
15712         return restart;
15713     }
15714
15715     // =========================================================
15716     // SERVICES
15717     // =========================================================
15718
15719     @Override
15720     public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
15721             int flags) {
15722         enforceNotIsolatedCaller("getServices");
15723         synchronized (this) {
15724             return mServices.getRunningServiceInfoLocked(maxNum, flags);
15725         }
15726     }
15727
15728     @Override
15729     public PendingIntent getRunningServiceControlPanel(ComponentName name) {
15730         enforceNotIsolatedCaller("getRunningServiceControlPanel");
15731         synchronized (this) {
15732             return mServices.getRunningServiceControlPanelLocked(name);
15733         }
15734     }
15735
15736     @Override
15737     public ComponentName startService(IApplicationThread caller, Intent service,
15738             String resolvedType, String callingPackage, int userId)
15739             throws TransactionTooLargeException {
15740         enforceNotIsolatedCaller("startService");
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         if (callingPackage == null) {
15747             throw new IllegalArgumentException("callingPackage cannot be null");
15748         }
15749
15750         if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
15751                 "startService: " + service + " type=" + resolvedType);
15752         synchronized(this) {
15753             final int callingPid = Binder.getCallingPid();
15754             final int callingUid = Binder.getCallingUid();
15755             final long origId = Binder.clearCallingIdentity();
15756             ComponentName res = mServices.startServiceLocked(caller, service,
15757                     resolvedType, callingPid, callingUid, callingPackage, userId);
15758             Binder.restoreCallingIdentity(origId);
15759             return res;
15760         }
15761     }
15762
15763     ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
15764             String callingPackage, int userId)
15765             throws TransactionTooLargeException {
15766         synchronized(this) {
15767             if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
15768                     "startServiceInPackage: " + service + " type=" + resolvedType);
15769             final long origId = Binder.clearCallingIdentity();
15770             ComponentName res = mServices.startServiceLocked(null, service,
15771                     resolvedType, -1, uid, callingPackage, userId);
15772             Binder.restoreCallingIdentity(origId);
15773             return res;
15774         }
15775     }
15776
15777     @Override
15778     public int stopService(IApplicationThread caller, Intent service,
15779             String resolvedType, int userId) {
15780         enforceNotIsolatedCaller("stopService");
15781         // Refuse possible leaked file descriptors
15782         if (service != null && service.hasFileDescriptors() == true) {
15783             throw new IllegalArgumentException("File descriptors passed in Intent");
15784         }
15785
15786         synchronized(this) {
15787             return mServices.stopServiceLocked(caller, service, resolvedType, userId);
15788         }
15789     }
15790
15791     @Override
15792     public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
15793         enforceNotIsolatedCaller("peekService");
15794         // Refuse possible leaked file descriptors
15795         if (service != null && service.hasFileDescriptors() == true) {
15796             throw new IllegalArgumentException("File descriptors passed in Intent");
15797         }
15798
15799         if (callingPackage == null) {
15800             throw new IllegalArgumentException("callingPackage cannot be null");
15801         }
15802
15803         synchronized(this) {
15804             return mServices.peekServiceLocked(service, resolvedType, callingPackage);
15805         }
15806     }
15807
15808     @Override
15809     public boolean stopServiceToken(ComponentName className, IBinder token,
15810             int startId) {
15811         synchronized(this) {
15812             return mServices.stopServiceTokenLocked(className, token, startId);
15813         }
15814     }
15815
15816     @Override
15817     public void setServiceForeground(ComponentName className, IBinder token,
15818             int id, Notification notification, boolean removeNotification) {
15819         synchronized(this) {
15820             mServices.setServiceForegroundLocked(className, token, id, notification,
15821                     removeNotification);
15822         }
15823     }
15824
15825     @Override
15826     public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
15827             boolean requireFull, String name, String callerPackage) {
15828         return handleIncomingUser(callingPid, callingUid, userId, allowAll,
15829                 requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
15830     }
15831
15832     int unsafeConvertIncomingUser(int userId) {
15833         return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
15834                 ? mCurrentUserId : userId;
15835     }
15836
15837     int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
15838             int allowMode, String name, String callerPackage) {
15839         final int callingUserId = UserHandle.getUserId(callingUid);
15840         if (callingUserId == userId) {
15841             return userId;
15842         }
15843
15844         // Note that we may be accessing mCurrentUserId outside of a lock...
15845         // shouldn't be a big deal, if this is being called outside
15846         // of a locked context there is intrinsically a race with
15847         // the value the caller will receive and someone else changing it.
15848         // We assume that USER_CURRENT_OR_SELF will use the current user; later
15849         // we will switch to the calling user if access to the current user fails.
15850         int targetUserId = unsafeConvertIncomingUser(userId);
15851
15852         if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
15853             final boolean allow;
15854             if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
15855                     callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
15856                 // If the caller has this permission, they always pass go.  And collect $200.
15857                 allow = true;
15858             } else if (allowMode == ALLOW_FULL_ONLY) {
15859                 // We require full access, sucks to be you.
15860                 allow = false;
15861             } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
15862                     callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
15863                 // If the caller does not have either permission, they are always doomed.
15864                 allow = false;
15865             } else if (allowMode == ALLOW_NON_FULL) {
15866                 // We are blanket allowing non-full access, you lucky caller!
15867                 allow = true;
15868             } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
15869                 // We may or may not allow this depending on whether the two users are
15870                 // in the same profile.
15871                 synchronized (mUserProfileGroupIdsSelfLocked) {
15872                     int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
15873                             UserInfo.NO_PROFILE_GROUP_ID);
15874                     int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
15875                             UserInfo.NO_PROFILE_GROUP_ID);
15876                     allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
15877                             && callingProfile == targetProfile;
15878                 }
15879             } else {
15880                 throw new IllegalArgumentException("Unknown mode: " + allowMode);
15881             }
15882             if (!allow) {
15883                 if (userId == UserHandle.USER_CURRENT_OR_SELF) {
15884                     // In this case, they would like to just execute as their
15885                     // owner user instead of failing.
15886                     targetUserId = callingUserId;
15887                 } else {
15888                     StringBuilder builder = new StringBuilder(128);
15889                     builder.append("Permission Denial: ");
15890                     builder.append(name);
15891                     if (callerPackage != null) {
15892                         builder.append(" from ");
15893                         builder.append(callerPackage);
15894                     }
15895                     builder.append(" asks to run as user ");
15896                     builder.append(userId);
15897                     builder.append(" but is calling from user ");
15898                     builder.append(UserHandle.getUserId(callingUid));
15899                     builder.append("; this requires ");
15900                     builder.append(INTERACT_ACROSS_USERS_FULL);
15901                     if (allowMode != ALLOW_FULL_ONLY) {
15902                         builder.append(" or ");
15903                         builder.append(INTERACT_ACROSS_USERS);
15904                     }
15905                     String msg = builder.toString();
15906                     Slog.w(TAG, msg);
15907                     throw new SecurityException(msg);
15908                 }
15909             }
15910         }
15911         if (!allowAll && targetUserId < 0) {
15912             throw new IllegalArgumentException(
15913                     "Call does not support special user #" + targetUserId);
15914         }
15915         // Check shell permission
15916         if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) {
15917             if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES,
15918                     targetUserId)) {
15919                 throw new SecurityException("Shell does not have permission to access user "
15920                         + targetUserId + "\n " + Debug.getCallers(3));
15921             }
15922         }
15923         return targetUserId;
15924     }
15925
15926     boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
15927             String className, int flags) {
15928         boolean result = false;
15929         // For apps that don't have pre-defined UIDs, check for permission
15930         if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
15931             if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
15932                 if (ActivityManager.checkUidPermission(
15933                         INTERACT_ACROSS_USERS,
15934                         aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
15935                     ComponentName comp = new ComponentName(aInfo.packageName, className);
15936                     String msg = "Permission Denial: Component " + comp.flattenToShortString()
15937                             + " requests FLAG_SINGLE_USER, but app does not hold "
15938                             + INTERACT_ACROSS_USERS;
15939                     Slog.w(TAG, msg);
15940                     throw new SecurityException(msg);
15941                 }
15942                 // Permission passed
15943                 result = true;
15944             }
15945         } else if ("system".equals(componentProcessName)) {
15946             result = true;
15947         } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
15948             // Phone app and persistent apps are allowed to export singleuser providers.
15949             result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
15950                     || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
15951         }
15952         if (DEBUG_MU) Slog.v(TAG_MU,
15953                 "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
15954                 + Integer.toHexString(flags) + ") = " + result);
15955         return result;
15956     }
15957
15958     /**
15959      * Checks to see if the caller is in the same app as the singleton
15960      * component, or the component is in a special app. It allows special apps
15961      * to export singleton components but prevents exporting singleton
15962      * components for regular apps.
15963      */
15964     boolean isValidSingletonCall(int callingUid, int componentUid) {
15965         int componentAppId = UserHandle.getAppId(componentUid);
15966         return UserHandle.isSameApp(callingUid, componentUid)
15967                 || componentAppId == Process.SYSTEM_UID
15968                 || componentAppId == Process.PHONE_UID
15969                 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
15970                         == PackageManager.PERMISSION_GRANTED;
15971     }
15972
15973     public int bindService(IApplicationThread caller, IBinder token, Intent service,
15974             String resolvedType, IServiceConnection connection, int flags, String callingPackage,
15975             int userId) throws TransactionTooLargeException {
15976         enforceNotIsolatedCaller("bindService");
15977
15978         // Refuse possible leaked file descriptors
15979         if (service != null && service.hasFileDescriptors() == true) {
15980             throw new IllegalArgumentException("File descriptors passed in Intent");
15981         }
15982
15983         if (callingPackage == null) {
15984             throw new IllegalArgumentException("callingPackage cannot be null");
15985         }
15986
15987         synchronized(this) {
15988             return mServices.bindServiceLocked(caller, token, service,
15989                     resolvedType, connection, flags, callingPackage, userId);
15990         }
15991     }
15992
15993     public boolean unbindService(IServiceConnection connection) {
15994         synchronized (this) {
15995             return mServices.unbindServiceLocked(connection);
15996         }
15997     }
15998
15999     public void publishService(IBinder token, Intent intent, IBinder service) {
16000         // Refuse possible leaked file descriptors
16001         if (intent != null && intent.hasFileDescriptors() == true) {
16002             throw new IllegalArgumentException("File descriptors passed in Intent");
16003         }
16004
16005         synchronized(this) {
16006             if (!(token instanceof ServiceRecord)) {
16007                 throw new IllegalArgumentException("Invalid service token");
16008             }
16009             mServices.publishServiceLocked((ServiceRecord)token, intent, service);
16010         }
16011     }
16012
16013     public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
16014         // Refuse possible leaked file descriptors
16015         if (intent != null && intent.hasFileDescriptors() == true) {
16016             throw new IllegalArgumentException("File descriptors passed in Intent");
16017         }
16018
16019         synchronized(this) {
16020             mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
16021         }
16022     }
16023
16024     public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
16025         synchronized(this) {
16026             if (!(token instanceof ServiceRecord)) {
16027                 Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
16028                 throw new IllegalArgumentException("Invalid service token");
16029             }
16030             mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
16031         }
16032     }
16033
16034     // =========================================================
16035     // BACKUP AND RESTORE
16036     // =========================================================
16037
16038     // Cause the target app to be launched if necessary and its backup agent
16039     // instantiated.  The backup agent will invoke backupAgentCreated() on the
16040     // activity manager to announce its creation.
16041     public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
16042         if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
16043                 "bindBackupAgent: app=" + app + " mode=" + backupMode);
16044         enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
16045
16046         synchronized(this) {
16047             // !!! TODO: currently no check here that we're already bound
16048             BatteryStatsImpl.Uid.Pkg.Serv ss = null;
16049             BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16050             synchronized (stats) {
16051                 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
16052             }
16053
16054             // Backup agent is now in use, its package can't be stopped.
16055             try {
16056                 AppGlobals.getPackageManager().setPackageStoppedState(
16057                         app.packageName, false, UserHandle.getUserId(app.uid));
16058             } catch (RemoteException e) {
16059             } catch (IllegalArgumentException e) {
16060                 Slog.w(TAG, "Failed trying to unstop package "
16061                         + app.packageName + ": " + e);
16062             }
16063
16064             BackupRecord r = new BackupRecord(ss, app, backupMode);
16065             ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
16066                     ? new ComponentName(app.packageName, app.backupAgentName)
16067                     : new ComponentName("android", "FullBackupAgent");
16068             // startProcessLocked() returns existing proc's record if it's already running
16069             ProcessRecord proc = startProcessLocked(app.processName, app,
16070                     false, 0, "backup", hostingName, false, false, false);
16071             if (proc == null) {
16072                 Slog.e(TAG, "Unable to start backup agent process " + r);
16073                 return false;
16074             }
16075
16076             r.app = proc;
16077             mBackupTarget = r;
16078             mBackupAppName = app.packageName;
16079
16080             // Try not to kill the process during backup
16081             updateOomAdjLocked(proc);
16082
16083             // If the process is already attached, schedule the creation of the backup agent now.
16084             // If it is not yet live, this will be done when it attaches to the framework.
16085             if (proc.thread != null) {
16086                 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
16087                 try {
16088                     proc.thread.scheduleCreateBackupAgent(app,
16089                             compatibilityInfoForPackageLocked(app), backupMode);
16090                 } catch (RemoteException e) {
16091                     // Will time out on the backup manager side
16092                 }
16093             } else {
16094                 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
16095             }
16096             // Invariants: at this point, the target app process exists and the application
16097             // is either already running or in the process of coming up.  mBackupTarget and
16098             // mBackupAppName describe the app, so that when it binds back to the AM we
16099             // know that it's scheduled for a backup-agent operation.
16100         }
16101
16102         return true;
16103     }
16104
16105     @Override
16106     public void clearPendingBackup() {
16107         if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
16108         enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
16109
16110         synchronized (this) {
16111             mBackupTarget = null;
16112             mBackupAppName = null;
16113         }
16114     }
16115
16116     // A backup agent has just come up
16117     public void backupAgentCreated(String agentPackageName, IBinder agent) {
16118         if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
16119                 + " = " + agent);
16120
16121         synchronized(this) {
16122             if (!agentPackageName.equals(mBackupAppName)) {
16123                 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
16124                 return;
16125             }
16126         }
16127
16128         long oldIdent = Binder.clearCallingIdentity();
16129         try {
16130             IBackupManager bm = IBackupManager.Stub.asInterface(
16131                     ServiceManager.getService(Context.BACKUP_SERVICE));
16132             bm.agentConnected(agentPackageName, agent);
16133         } catch (RemoteException e) {
16134             // can't happen; the backup manager service is local
16135         } catch (Exception e) {
16136             Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
16137             e.printStackTrace();
16138         } finally {
16139             Binder.restoreCallingIdentity(oldIdent);
16140         }
16141     }
16142
16143     // done with this agent
16144     public void unbindBackupAgent(ApplicationInfo appInfo) {
16145         if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
16146         if (appInfo == null) {
16147             Slog.w(TAG, "unbind backup agent for null app");
16148             return;
16149         }
16150
16151         synchronized(this) {
16152             try {
16153                 if (mBackupAppName == null) {
16154                     Slog.w(TAG, "Unbinding backup agent with no active backup");
16155                     return;
16156                 }
16157
16158                 if (!mBackupAppName.equals(appInfo.packageName)) {
16159                     Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
16160                     return;
16161                 }
16162
16163                 // Not backing this app up any more; reset its OOM adjustment
16164                 final ProcessRecord proc = mBackupTarget.app;
16165                 updateOomAdjLocked(proc);
16166
16167                 // If the app crashed during backup, 'thread' will be null here
16168                 if (proc.thread != null) {
16169                     try {
16170                         proc.thread.scheduleDestroyBackupAgent(appInfo,
16171                                 compatibilityInfoForPackageLocked(appInfo));
16172                     } catch (Exception e) {
16173                         Slog.e(TAG, "Exception when unbinding backup agent:");
16174                         e.printStackTrace();
16175                     }
16176                 }
16177             } finally {
16178                 mBackupTarget = null;
16179                 mBackupAppName = null;
16180             }
16181         }
16182     }
16183     // =========================================================
16184     // BROADCASTS
16185     // =========================================================
16186
16187     boolean isPendingBroadcastProcessLocked(int pid) {
16188         return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
16189                 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
16190     }
16191
16192     void skipPendingBroadcastLocked(int pid) {
16193             Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
16194             for (BroadcastQueue queue : mBroadcastQueues) {
16195                 queue.skipPendingBroadcastLocked(pid);
16196             }
16197     }
16198
16199     // The app just attached; send any pending broadcasts that it should receive
16200     boolean sendPendingBroadcastsLocked(ProcessRecord app) {
16201         boolean didSomething = false;
16202         for (BroadcastQueue queue : mBroadcastQueues) {
16203             didSomething |= queue.sendPendingBroadcastsLocked(app);
16204         }
16205         return didSomething;
16206     }
16207
16208     public Intent registerReceiver(IApplicationThread caller, String callerPackage,
16209             IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
16210         enforceNotIsolatedCaller("registerReceiver");
16211         ArrayList<Intent> stickyIntents = null;
16212         ProcessRecord callerApp = null;
16213         int callingUid;
16214         int callingPid;
16215         synchronized(this) {
16216             if (caller != null) {
16217                 callerApp = getRecordForAppLocked(caller);
16218                 if (callerApp == null) {
16219                     throw new SecurityException(
16220                             "Unable to find app for caller " + caller
16221                             + " (pid=" + Binder.getCallingPid()
16222                             + ") when registering receiver " + receiver);
16223                 }
16224                 if (callerApp.info.uid != Process.SYSTEM_UID &&
16225                         !callerApp.pkgList.containsKey(callerPackage) &&
16226                         !"android".equals(callerPackage)) {
16227                     throw new SecurityException("Given caller package " + callerPackage
16228                             + " is not running in process " + callerApp);
16229                 }
16230                 callingUid = callerApp.info.uid;
16231                 callingPid = callerApp.pid;
16232             } else {
16233                 callerPackage = null;
16234                 callingUid = Binder.getCallingUid();
16235                 callingPid = Binder.getCallingPid();
16236             }
16237
16238             userId = handleIncomingUser(callingPid, callingUid, userId,
16239                     true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
16240
16241             Iterator<String> actions = filter.actionsIterator();
16242             if (actions == null) {
16243                 ArrayList<String> noAction = new ArrayList<String>(1);
16244                 noAction.add(null);
16245                 actions = noAction.iterator();
16246             }
16247
16248             // Collect stickies of users
16249             int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
16250             while (actions.hasNext()) {
16251                 String action = actions.next();
16252                 for (int id : userIds) {
16253                     ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
16254                     if (stickies != null) {
16255                         ArrayList<Intent> intents = stickies.get(action);
16256                         if (intents != null) {
16257                             if (stickyIntents == null) {
16258                                 stickyIntents = new ArrayList<Intent>();
16259                             }
16260                             stickyIntents.addAll(intents);
16261                         }
16262                     }
16263                 }
16264             }
16265         }
16266
16267         ArrayList<Intent> allSticky = null;
16268         if (stickyIntents != null) {
16269             final ContentResolver resolver = mContext.getContentResolver();
16270             // Look for any matching sticky broadcasts...
16271             for (int i = 0, N = stickyIntents.size(); i < N; i++) {
16272                 Intent intent = stickyIntents.get(i);
16273                 // If intent has scheme "content", it will need to acccess
16274                 // provider that needs to lock mProviderMap in ActivityThread
16275                 // and also it may need to wait application response, so we
16276                 // cannot lock ActivityManagerService here.
16277                 if (filter.match(resolver, intent, true, TAG) >= 0) {
16278                     if (allSticky == null) {
16279                         allSticky = new ArrayList<Intent>();
16280                     }
16281                     allSticky.add(intent);
16282                 }
16283             }
16284         }
16285
16286         // The first sticky in the list is returned directly back to the client.
16287         Intent sticky = allSticky != null ? allSticky.get(0) : null;
16288         if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
16289         if (receiver == null) {
16290             return sticky;
16291         }
16292
16293         synchronized (this) {
16294             if (callerApp != null && (callerApp.thread == null
16295                     || callerApp.thread.asBinder() != caller.asBinder())) {
16296                 // Original caller already died
16297                 return null;
16298             }
16299             ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
16300             if (rl == null) {
16301                 rl = new ReceiverList(this, callerApp, callingPid, callingUid,
16302                         userId, receiver);
16303                 if (rl.app != null) {
16304                     rl.app.receivers.add(rl);
16305                 } else {
16306                     try {
16307                         receiver.asBinder().linkToDeath(rl, 0);
16308                     } catch (RemoteException e) {
16309                         return sticky;
16310                     }
16311                     rl.linkedToDeath = true;
16312                 }
16313                 mRegisteredReceivers.put(receiver.asBinder(), rl);
16314             } else if (rl.uid != callingUid) {
16315                 throw new IllegalArgumentException(
16316                         "Receiver requested to register for uid " + callingUid
16317                         + " was previously registered for uid " + rl.uid);
16318             } else if (rl.pid != callingPid) {
16319                 throw new IllegalArgumentException(
16320                         "Receiver requested to register for pid " + callingPid
16321                         + " was previously registered for pid " + rl.pid);
16322             } else if (rl.userId != userId) {
16323                 throw new IllegalArgumentException(
16324                         "Receiver requested to register for user " + userId
16325                         + " was previously registered for user " + rl.userId);
16326             }
16327             BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
16328                     permission, callingUid, userId);
16329             rl.add(bf);
16330             if (!bf.debugCheck()) {
16331                 Slog.w(TAG, "==> For Dynamic broadcast");
16332             }
16333             mReceiverResolver.addFilter(bf);
16334
16335             // Enqueue broadcasts for all existing stickies that match
16336             // this filter.
16337             if (allSticky != null) {
16338                 ArrayList receivers = new ArrayList();
16339                 receivers.add(bf);
16340
16341                 final int stickyCount = allSticky.size();
16342                 for (int i = 0; i < stickyCount; i++) {
16343                     Intent intent = allSticky.get(i);
16344                     BroadcastQueue queue = broadcastQueueForIntent(intent);
16345                     BroadcastRecord r = new BroadcastRecord(queue, intent, null,
16346                             null, -1, -1, null, null, AppOpsManager.OP_NONE, null, receivers,
16347                             null, 0, null, null, false, true, true, -1);
16348                     queue.enqueueParallelBroadcastLocked(r);
16349                     queue.scheduleBroadcastsLocked();
16350                 }
16351             }
16352
16353             return sticky;
16354         }
16355     }
16356
16357     public void unregisterReceiver(IIntentReceiver receiver) {
16358         if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
16359
16360         final long origId = Binder.clearCallingIdentity();
16361         try {
16362             boolean doTrim = false;
16363
16364             synchronized(this) {
16365                 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
16366                 if (rl != null) {
16367                     final BroadcastRecord r = rl.curBroadcast;
16368                     if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
16369                         final boolean doNext = r.queue.finishReceiverLocked(
16370                                 r, r.resultCode, r.resultData, r.resultExtras,
16371                                 r.resultAbort, false);
16372                         if (doNext) {
16373                             doTrim = true;
16374                             r.queue.processNextBroadcast(false);
16375                         }
16376                     }
16377
16378                     if (rl.app != null) {
16379                         rl.app.receivers.remove(rl);
16380                     }
16381                     removeReceiverLocked(rl);
16382                     if (rl.linkedToDeath) {
16383                         rl.linkedToDeath = false;
16384                         rl.receiver.asBinder().unlinkToDeath(rl, 0);
16385                     }
16386                 }
16387             }
16388
16389             // If we actually concluded any broadcasts, we might now be able
16390             // to trim the recipients' apps from our working set
16391             if (doTrim) {
16392                 trimApplications();
16393                 return;
16394             }
16395
16396         } finally {
16397             Binder.restoreCallingIdentity(origId);
16398         }
16399     }
16400
16401     void removeReceiverLocked(ReceiverList rl) {
16402         mRegisteredReceivers.remove(rl.receiver.asBinder());
16403         for (int i = rl.size() - 1; i >= 0; i--) {
16404             mReceiverResolver.removeFilter(rl.get(i));
16405         }
16406     }
16407
16408     private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
16409         for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
16410             ProcessRecord r = mLruProcesses.get(i);
16411             if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
16412                 try {
16413                     r.thread.dispatchPackageBroadcast(cmd, packages);
16414                 } catch (RemoteException ex) {
16415                 }
16416             }
16417         }
16418     }
16419
16420     private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
16421             int callingUid, int[] users) {
16422         List<ResolveInfo> receivers = null;
16423         try {
16424             HashSet<ComponentName> singleUserReceivers = null;
16425             boolean scannedFirstReceivers = false;
16426             for (int user : users) {
16427                 // Skip users that have Shell restrictions
16428                 if (callingUid == Process.SHELL_UID
16429                         && getUserManagerLocked().hasUserRestriction(
16430                                 UserManager.DISALLOW_DEBUGGING_FEATURES, user)) {
16431                     continue;
16432                 }
16433                 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
16434                         .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
16435                 if (user != UserHandle.USER_OWNER && newReceivers != null) {
16436                     // If this is not the primary user, we need to check for
16437                     // any receivers that should be filtered out.
16438                     for (int i=0; i<newReceivers.size(); i++) {
16439                         ResolveInfo ri = newReceivers.get(i);
16440                         if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
16441                             newReceivers.remove(i);
16442                             i--;
16443                         }
16444                     }
16445                 }
16446                 if (newReceivers != null && newReceivers.size() == 0) {
16447                     newReceivers = null;
16448                 }
16449                 if (receivers == null) {
16450                     receivers = newReceivers;
16451                 } else if (newReceivers != null) {
16452                     // We need to concatenate the additional receivers
16453                     // found with what we have do far.  This would be easy,
16454                     // but we also need to de-dup any receivers that are
16455                     // singleUser.
16456                     if (!scannedFirstReceivers) {
16457                         // Collect any single user receivers we had already retrieved.
16458                         scannedFirstReceivers = true;
16459                         for (int i=0; i<receivers.size(); i++) {
16460                             ResolveInfo ri = receivers.get(i);
16461                             if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
16462                                 ComponentName cn = new ComponentName(
16463                                         ri.activityInfo.packageName, ri.activityInfo.name);
16464                                 if (singleUserReceivers == null) {
16465                                     singleUserReceivers = new HashSet<ComponentName>();
16466                                 }
16467                                 singleUserReceivers.add(cn);
16468                             }
16469                         }
16470                     }
16471                     // Add the new results to the existing results, tracking
16472                     // and de-dupping single user receivers.
16473                     for (int i=0; i<newReceivers.size(); i++) {
16474                         ResolveInfo ri = newReceivers.get(i);
16475                         if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
16476                             ComponentName cn = new ComponentName(
16477                                     ri.activityInfo.packageName, ri.activityInfo.name);
16478                             if (singleUserReceivers == null) {
16479                                 singleUserReceivers = new HashSet<ComponentName>();
16480                             }
16481                             if (!singleUserReceivers.contains(cn)) {
16482                                 singleUserReceivers.add(cn);
16483                                 receivers.add(ri);
16484                             }
16485                         } else {
16486                             receivers.add(ri);
16487                         }
16488                     }
16489                 }
16490             }
16491         } catch (RemoteException ex) {
16492             // pm is in same process, this will never happen.
16493         }
16494         return receivers;
16495     }
16496
16497     private final int broadcastIntentLocked(ProcessRecord callerApp,
16498             String callerPackage, Intent intent, String resolvedType,
16499             IIntentReceiver resultTo, int resultCode, String resultData,
16500             Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle options,
16501             boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
16502         intent = new Intent(intent);
16503
16504         // By default broadcasts do not go to stopped apps.
16505         intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
16506
16507         // If we have not finished booting, don't allow this to launch new processes.
16508         if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
16509             intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16510         }
16511
16512         if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
16513                 (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
16514                 + " ordered=" + ordered + " userid=" + userId);
16515         if ((resultTo != null) && !ordered) {
16516             Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
16517         }
16518
16519         userId = handleIncomingUser(callingPid, callingUid, userId,
16520                 true, ALLOW_NON_FULL, "broadcast", callerPackage);
16521
16522         // Make sure that the user who is receiving this broadcast is running.
16523         // If not, we will just skip it. Make an exception for shutdown broadcasts
16524         // and upgrade steps.
16525
16526         if (userId != UserHandle.USER_ALL && !isUserRunningLocked(userId, false)) {
16527             if ((callingUid != Process.SYSTEM_UID
16528                     || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
16529                     && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
16530                 Slog.w(TAG, "Skipping broadcast of " + intent
16531                         + ": user " + userId + " is stopped");
16532                 return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
16533             }
16534         }
16535
16536         BroadcastOptions brOptions = null;
16537         if (options != null) {
16538             brOptions = new BroadcastOptions(options);
16539             if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
16540                 // See if the caller is allowed to do this.  Note we are checking against
16541                 // the actual real caller (not whoever provided the operation as say a
16542                 // PendingIntent), because that who is actually supplied the arguments.
16543                 if (checkComponentPermission(
16544                         android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
16545                         Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
16546                         != PackageManager.PERMISSION_GRANTED) {
16547                     String msg = "Permission Denial: " + intent.getAction()
16548                             + " broadcast from " + callerPackage + " (pid=" + callingPid
16549                             + ", uid=" + callingUid + ")"
16550                             + " requires "
16551                             + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
16552                     Slog.w(TAG, msg);
16553                     throw new SecurityException(msg);
16554                 }
16555             }
16556         }
16557
16558         /*
16559          * Prevent non-system code (defined here to be non-persistent
16560          * processes) from sending protected broadcasts.
16561          */
16562         int callingAppId = UserHandle.getAppId(callingUid);
16563         if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
16564             || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
16565             || callingAppId == Process.NFC_UID || callingUid == 0) {
16566             // Always okay.
16567         } else if (callerApp == null || !callerApp.persistent) {
16568             try {
16569                 if (AppGlobals.getPackageManager().isProtectedBroadcast(
16570                         intent.getAction())) {
16571                     String msg = "Permission Denial: not allowed to send broadcast "
16572                             + intent.getAction() + " from pid="
16573                             + callingPid + ", uid=" + callingUid;
16574                     Slog.w(TAG, msg);
16575                     throw new SecurityException(msg);
16576                 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
16577                     // Special case for compatibility: we don't want apps to send this,
16578                     // but historically it has not been protected and apps may be using it
16579                     // to poke their own app widget.  So, instead of making it protected,
16580                     // just limit it to the caller.
16581                     if (callerApp == null) {
16582                         String msg = "Permission Denial: not allowed to send broadcast "
16583                                 + intent.getAction() + " from unknown caller.";
16584                         Slog.w(TAG, msg);
16585                         throw new SecurityException(msg);
16586                     } else if (intent.getComponent() != null) {
16587                         // They are good enough to send to an explicit component...  verify
16588                         // it is being sent to the calling app.
16589                         if (!intent.getComponent().getPackageName().equals(
16590                                 callerApp.info.packageName)) {
16591                             String msg = "Permission Denial: not allowed to send broadcast "
16592                                     + intent.getAction() + " to "
16593                                     + intent.getComponent().getPackageName() + " from "
16594                                     + callerApp.info.packageName;
16595                             Slog.w(TAG, msg);
16596                             throw new SecurityException(msg);
16597                         }
16598                     } else {
16599                         // Limit broadcast to their own package.
16600                         intent.setPackage(callerApp.info.packageName);
16601                     }
16602                 }
16603             } catch (RemoteException e) {
16604                 Slog.w(TAG, "Remote exception", e);
16605                 return ActivityManager.BROADCAST_SUCCESS;
16606             }
16607         }
16608
16609         final String action = intent.getAction();
16610         if (action != null) {
16611             switch (action) {
16612                 case Intent.ACTION_UID_REMOVED:
16613                 case Intent.ACTION_PACKAGE_REMOVED:
16614                 case Intent.ACTION_PACKAGE_CHANGED:
16615                 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
16616                 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
16617                     // Handle special intents: if this broadcast is from the package
16618                     // manager about a package being removed, we need to remove all of
16619                     // its activities from the history stack.
16620                     if (checkComponentPermission(
16621                             android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
16622                             callingPid, callingUid, -1, true)
16623                             != PackageManager.PERMISSION_GRANTED) {
16624                         String msg = "Permission Denial: " + intent.getAction()
16625                                 + " broadcast from " + callerPackage + " (pid=" + callingPid
16626                                 + ", uid=" + callingUid + ")"
16627                                 + " requires "
16628                                 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
16629                         Slog.w(TAG, msg);
16630                         throw new SecurityException(msg);
16631                     }
16632                     switch (action) {
16633                         case Intent.ACTION_UID_REMOVED:
16634                             final Bundle intentExtras = intent.getExtras();
16635                             final int uid = intentExtras != null
16636                                     ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
16637                             if (uid >= 0) {
16638                                 mBatteryStatsService.removeUid(uid);
16639                                 mAppOpsService.uidRemoved(uid);
16640                             }
16641                             break;
16642                         case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
16643                             // If resources are unavailable just force stop all those packages
16644                             // and flush the attribute cache as well.
16645                             String list[] =
16646                                     intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
16647                             if (list != null && list.length > 0) {
16648                                 for (int i = 0; i < list.length; i++) {
16649                                     forceStopPackageLocked(list[i], -1, false, true, true,
16650                                             false, false, userId, "storage unmount");
16651                                 }
16652                                 mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
16653                                 sendPackageBroadcastLocked(
16654                                         IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
16655                                         userId);
16656                             }
16657                             break;
16658                         case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
16659                             mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
16660                             break;
16661                         case Intent.ACTION_PACKAGE_REMOVED:
16662                         case Intent.ACTION_PACKAGE_CHANGED:
16663                             Uri data = intent.getData();
16664                             String ssp;
16665                             if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
16666                                 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
16667                                 boolean fullUninstall = removed &&
16668                                         !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
16669                                 final boolean killProcess =
16670                                         !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
16671                                 if (killProcess) {
16672                                     forceStopPackageLocked(ssp, UserHandle.getAppId(
16673                                             intent.getIntExtra(Intent.EXTRA_UID, -1)),
16674                                             false, true, true, false, fullUninstall, userId,
16675                                             removed ? "pkg removed" : "pkg changed");
16676                                 }
16677                                 if (removed) {
16678                                     sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
16679                                             new String[] {ssp}, userId);
16680                                     if (fullUninstall) {
16681                                         mAppOpsService.packageRemoved(
16682                                                 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
16683
16684                                         // Remove all permissions granted from/to this package
16685                                         removeUriPermissionsForPackageLocked(ssp, userId, true);
16686
16687                                         removeTasksByPackageNameLocked(ssp, userId);
16688                                         mBatteryStatsService.notePackageUninstalled(ssp);
16689                                     }
16690                                 } else {
16691                                     cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
16692                                             intent.getStringArrayExtra(
16693                                                     Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
16694                                 }
16695                             }
16696                             break;
16697                     }
16698                     break;
16699                 case Intent.ACTION_PACKAGE_ADDED:
16700                     // Special case for adding a package: by default turn on compatibility mode.
16701                     Uri data = intent.getData();
16702                     String ssp;
16703                     if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
16704                         final boolean replacing =
16705                                 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
16706                         mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
16707
16708                         try {
16709                             ApplicationInfo ai = AppGlobals.getPackageManager().
16710                                     getApplicationInfo(ssp, 0, 0);
16711                             mBatteryStatsService.notePackageInstalled(ssp,
16712                                     ai != null ? ai.versionCode : 0);
16713                         } catch (RemoteException e) {
16714                         }
16715                     }
16716                     break;
16717                 case Intent.ACTION_TIMEZONE_CHANGED:
16718                     // If this is the time zone changed action, queue up a message that will reset
16719                     // the timezone of all currently running processes. This message will get
16720                     // queued up before the broadcast happens.
16721                     mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
16722                     break;
16723                 case Intent.ACTION_TIME_CHANGED:
16724                     // If the user set the time, let all running processes know.
16725                     final int is24Hour =
16726                             intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
16727                                     : 0;
16728                     mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
16729                     BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16730                     synchronized (stats) {
16731                         stats.noteCurrentTimeChangedLocked();
16732                     }
16733                     break;
16734                 case Intent.ACTION_CLEAR_DNS_CACHE:
16735                     mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
16736                     break;
16737                 case Proxy.PROXY_CHANGE_ACTION:
16738                     ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
16739                     mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
16740                     break;
16741             }
16742         }
16743
16744         // Add to the sticky list if requested.
16745         if (sticky) {
16746             if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
16747                     callingPid, callingUid)
16748                     != PackageManager.PERMISSION_GRANTED) {
16749                 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
16750                         + callingPid + ", uid=" + callingUid
16751                         + " requires " + android.Manifest.permission.BROADCAST_STICKY;
16752                 Slog.w(TAG, msg);
16753                 throw new SecurityException(msg);
16754             }
16755             if (requiredPermissions != null && requiredPermissions.length > 0) {
16756                 Slog.w(TAG, "Can't broadcast sticky intent " + intent
16757                         + " and enforce permissions " + Arrays.toString(requiredPermissions));
16758                 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
16759             }
16760             if (intent.getComponent() != null) {
16761                 throw new SecurityException(
16762                         "Sticky broadcasts can't target a specific component");
16763             }
16764             // We use userId directly here, since the "all" target is maintained
16765             // as a separate set of sticky broadcasts.
16766             if (userId != UserHandle.USER_ALL) {
16767                 // But first, if this is not a broadcast to all users, then
16768                 // make sure it doesn't conflict with an existing broadcast to
16769                 // all users.
16770                 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
16771                         UserHandle.USER_ALL);
16772                 if (stickies != null) {
16773                     ArrayList<Intent> list = stickies.get(intent.getAction());
16774                     if (list != null) {
16775                         int N = list.size();
16776                         int i;
16777                         for (i=0; i<N; i++) {
16778                             if (intent.filterEquals(list.get(i))) {
16779                                 throw new IllegalArgumentException(
16780                                         "Sticky broadcast " + intent + " for user "
16781                                         + userId + " conflicts with existing global broadcast");
16782                             }
16783                         }
16784                     }
16785                 }
16786             }
16787             ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
16788             if (stickies == null) {
16789                 stickies = new ArrayMap<>();
16790                 mStickyBroadcasts.put(userId, stickies);
16791             }
16792             ArrayList<Intent> list = stickies.get(intent.getAction());
16793             if (list == null) {
16794                 list = new ArrayList<>();
16795                 stickies.put(intent.getAction(), list);
16796             }
16797             final int stickiesCount = list.size();
16798             int i;
16799             for (i = 0; i < stickiesCount; i++) {
16800                 if (intent.filterEquals(list.get(i))) {
16801                     // This sticky already exists, replace it.
16802                     list.set(i, new Intent(intent));
16803                     break;
16804                 }
16805             }
16806             if (i >= stickiesCount) {
16807                 list.add(new Intent(intent));
16808             }
16809         }
16810
16811         int[] users;
16812         if (userId == UserHandle.USER_ALL) {
16813             // Caller wants broadcast to go to all started users.
16814             users = mStartedUserArray;
16815         } else {
16816             // Caller wants broadcast to go to one specific user.
16817             users = new int[] {userId};
16818         }
16819
16820         // Figure out who all will receive this broadcast.
16821         List receivers = null;
16822         List<BroadcastFilter> registeredReceivers = null;
16823         // Need to resolve the intent to interested receivers...
16824         if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
16825                  == 0) {
16826             receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
16827         }
16828         if (intent.getComponent() == null) {
16829             if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
16830                 // Query one target user at a time, excluding shell-restricted users
16831                 UserManagerService ums = getUserManagerLocked();
16832                 for (int i = 0; i < users.length; i++) {
16833                     if (ums.hasUserRestriction(
16834                             UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
16835                         continue;
16836                     }
16837                     List<BroadcastFilter> registeredReceiversForUser =
16838                             mReceiverResolver.queryIntent(intent,
16839                                     resolvedType, false, users[i]);
16840                     if (registeredReceivers == null) {
16841                         registeredReceivers = registeredReceiversForUser;
16842                     } else if (registeredReceiversForUser != null) {
16843                         registeredReceivers.addAll(registeredReceiversForUser);
16844                     }
16845                 }
16846             } else {
16847                 registeredReceivers = mReceiverResolver.queryIntent(intent,
16848                         resolvedType, false, userId);
16849             }
16850         }
16851
16852         final boolean replacePending =
16853                 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
16854
16855         if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueing broadcast: " + intent.getAction()
16856                 + " replacePending=" + replacePending);
16857
16858         int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
16859         if (!ordered && NR > 0) {
16860             // If we are not serializing this broadcast, then send the
16861             // registered receivers separately so they don't wait for the
16862             // components to be launched.
16863             final BroadcastQueue queue = broadcastQueueForIntent(intent);
16864             BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
16865                     callerPackage, callingPid, callingUid, resolvedType, requiredPermissions,
16866                     appOp, brOptions, registeredReceivers, resultTo, resultCode, resultData,
16867                     resultExtras, ordered, sticky, false, userId);
16868             if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
16869             final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
16870             if (!replaced) {
16871                 queue.enqueueParallelBroadcastLocked(r);
16872                 queue.scheduleBroadcastsLocked();
16873             }
16874             registeredReceivers = null;
16875             NR = 0;
16876         }
16877
16878         // Merge into one list.
16879         int ir = 0;
16880         if (receivers != null) {
16881             // A special case for PACKAGE_ADDED: do not allow the package
16882             // being added to see this broadcast.  This prevents them from
16883             // using this as a back door to get run as soon as they are
16884             // installed.  Maybe in the future we want to have a special install
16885             // broadcast or such for apps, but we'd like to deliberately make
16886             // this decision.
16887             String skipPackages[] = null;
16888             if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
16889                     || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
16890                     || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
16891                 Uri data = intent.getData();
16892                 if (data != null) {
16893                     String pkgName = data.getSchemeSpecificPart();
16894                     if (pkgName != null) {
16895                         skipPackages = new String[] { pkgName };
16896                     }
16897                 }
16898             } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
16899                 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
16900             }
16901             if (skipPackages != null && (skipPackages.length > 0)) {
16902                 for (String skipPackage : skipPackages) {
16903                     if (skipPackage != null) {
16904                         int NT = receivers.size();
16905                         for (int it=0; it<NT; it++) {
16906                             ResolveInfo curt = (ResolveInfo)receivers.get(it);
16907                             if (curt.activityInfo.packageName.equals(skipPackage)) {
16908                                 receivers.remove(it);
16909                                 it--;
16910                                 NT--;
16911                             }
16912                         }
16913                     }
16914                 }
16915             }
16916
16917             int NT = receivers != null ? receivers.size() : 0;
16918             int it = 0;
16919             ResolveInfo curt = null;
16920             BroadcastFilter curr = null;
16921             while (it < NT && ir < NR) {
16922                 if (curt == null) {
16923                     curt = (ResolveInfo)receivers.get(it);
16924                 }
16925                 if (curr == null) {
16926                     curr = registeredReceivers.get(ir);
16927                 }
16928                 if (curr.getPriority() >= curt.priority) {
16929                     // Insert this broadcast record into the final list.
16930                     receivers.add(it, curr);
16931                     ir++;
16932                     curr = null;
16933                     it++;
16934                     NT++;
16935                 } else {
16936                     // Skip to the next ResolveInfo in the final list.
16937                     it++;
16938                     curt = null;
16939                 }
16940             }
16941         }
16942         while (ir < NR) {
16943             if (receivers == null) {
16944                 receivers = new ArrayList();
16945             }
16946             receivers.add(registeredReceivers.get(ir));
16947             ir++;
16948         }
16949
16950         if ((receivers != null && receivers.size() > 0)
16951                 || resultTo != null) {
16952             BroadcastQueue queue = broadcastQueueForIntent(intent);
16953             BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
16954                     callerPackage, callingPid, callingUid, resolvedType,
16955                     requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
16956                     resultData, resultExtras, ordered, sticky, false, userId);
16957
16958             if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
16959                     + ": prev had " + queue.mOrderedBroadcasts.size());
16960             if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
16961                     "Enqueueing broadcast " + r.intent.getAction());
16962
16963             boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
16964             if (!replaced) {
16965                 queue.enqueueOrderedBroadcastLocked(r);
16966                 queue.scheduleBroadcastsLocked();
16967             }
16968         }
16969
16970         return ActivityManager.BROADCAST_SUCCESS;
16971     }
16972
16973     final Intent verifyBroadcastLocked(Intent intent) {
16974         // Refuse possible leaked file descriptors
16975         if (intent != null && intent.hasFileDescriptors() == true) {
16976             throw new IllegalArgumentException("File descriptors passed in Intent");
16977         }
16978
16979         int flags = intent.getFlags();
16980
16981         if (!mProcessesReady) {
16982             // if the caller really truly claims to know what they're doing, go
16983             // ahead and allow the broadcast without launching any receivers
16984             if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
16985                 // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
16986             } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
16987                 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
16988                         + " before boot completion");
16989                 throw new IllegalStateException("Cannot broadcast before boot completed");
16990             }
16991         }
16992
16993         if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
16994             throw new IllegalArgumentException(
16995                     "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
16996         }
16997
16998         return intent;
16999     }
17000
17001     public final int broadcastIntent(IApplicationThread caller,
17002             Intent intent, String resolvedType, IIntentReceiver resultTo,
17003             int resultCode, String resultData, Bundle resultExtras,
17004             String[] requiredPermissions, int appOp, Bundle options,
17005             boolean serialized, boolean sticky, int userId) {
17006         enforceNotIsolatedCaller("broadcastIntent");
17007         synchronized(this) {
17008             intent = verifyBroadcastLocked(intent);
17009
17010             final ProcessRecord callerApp = getRecordForAppLocked(caller);
17011             final int callingPid = Binder.getCallingPid();
17012             final int callingUid = Binder.getCallingUid();
17013             final long origId = Binder.clearCallingIdentity();
17014             int res = broadcastIntentLocked(callerApp,
17015                     callerApp != null ? callerApp.info.packageName : null,
17016                     intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
17017                     requiredPermissions, appOp, null, serialized, sticky,
17018                     callingPid, callingUid, userId);
17019             Binder.restoreCallingIdentity(origId);
17020             return res;
17021         }
17022     }
17023
17024
17025     int broadcastIntentInPackage(String packageName, int uid,
17026             Intent intent, String resolvedType, IIntentReceiver resultTo,
17027             int resultCode, String resultData, Bundle resultExtras,
17028             String requiredPermission, Bundle options, boolean serialized, boolean sticky,
17029             int userId) {
17030         synchronized(this) {
17031             intent = verifyBroadcastLocked(intent);
17032
17033             final long origId = Binder.clearCallingIdentity();
17034             String[] requiredPermissions = requiredPermission == null ? null
17035                     : new String[] {requiredPermission};
17036             int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
17037                     resultTo, resultCode, resultData, resultExtras,
17038                     requiredPermissions, AppOpsManager.OP_NONE, options, serialized,
17039                     sticky, -1, uid, userId);
17040             Binder.restoreCallingIdentity(origId);
17041             return res;
17042         }
17043     }
17044
17045     public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
17046         // Refuse possible leaked file descriptors
17047         if (intent != null && intent.hasFileDescriptors() == true) {
17048             throw new IllegalArgumentException("File descriptors passed in Intent");
17049         }
17050
17051         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17052                 userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
17053
17054         synchronized(this) {
17055             if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
17056                     != PackageManager.PERMISSION_GRANTED) {
17057                 String msg = "Permission Denial: unbroadcastIntent() from pid="
17058                         + Binder.getCallingPid()
17059                         + ", uid=" + Binder.getCallingUid()
17060                         + " requires " + android.Manifest.permission.BROADCAST_STICKY;
17061                 Slog.w(TAG, msg);
17062                 throw new SecurityException(msg);
17063             }
17064             ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
17065             if (stickies != null) {
17066                 ArrayList<Intent> list = stickies.get(intent.getAction());
17067                 if (list != null) {
17068                     int N = list.size();
17069                     int i;
17070                     for (i=0; i<N; i++) {
17071                         if (intent.filterEquals(list.get(i))) {
17072                             list.remove(i);
17073                             break;
17074                         }
17075                     }
17076                     if (list.size() <= 0) {
17077                         stickies.remove(intent.getAction());
17078                     }
17079                 }
17080                 if (stickies.size() <= 0) {
17081                     mStickyBroadcasts.remove(userId);
17082                 }
17083             }
17084         }
17085     }
17086
17087     void backgroundServicesFinishedLocked(int userId) {
17088         for (BroadcastQueue queue : mBroadcastQueues) {
17089             queue.backgroundServicesFinishedLocked(userId);
17090         }
17091     }
17092
17093     public void finishReceiver(IBinder who, int resultCode, String resultData,
17094             Bundle resultExtras, boolean resultAbort, int flags) {
17095         if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
17096
17097         // Refuse possible leaked file descriptors
17098         if (resultExtras != null && resultExtras.hasFileDescriptors()) {
17099             throw new IllegalArgumentException("File descriptors passed in Bundle");
17100         }
17101
17102         final long origId = Binder.clearCallingIdentity();
17103         try {
17104             boolean doNext = false;
17105             BroadcastRecord r;
17106
17107             synchronized(this) {
17108                 BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
17109                         ? mFgBroadcastQueue : mBgBroadcastQueue;
17110                 r = queue.getMatchingOrderedReceiver(who);
17111                 if (r != null) {
17112                     doNext = r.queue.finishReceiverLocked(r, resultCode,
17113                         resultData, resultExtras, resultAbort, true);
17114                 }
17115             }
17116
17117             if (doNext) {
17118                 r.queue.processNextBroadcast(false);
17119             }
17120             trimApplications();
17121         } finally {
17122             Binder.restoreCallingIdentity(origId);
17123         }
17124     }
17125
17126     // =========================================================
17127     // INSTRUMENTATION
17128     // =========================================================
17129
17130     public boolean startInstrumentation(ComponentName className,
17131             String profileFile, int flags, Bundle arguments,
17132             IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
17133             int userId, String abiOverride) {
17134         enforceNotIsolatedCaller("startInstrumentation");
17135         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17136                 userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
17137         // Refuse possible leaked file descriptors
17138         if (arguments != null && arguments.hasFileDescriptors()) {
17139             throw new IllegalArgumentException("File descriptors passed in Bundle");
17140         }
17141
17142         synchronized(this) {
17143             InstrumentationInfo ii = null;
17144             ApplicationInfo ai = null;
17145             try {
17146                 ii = mContext.getPackageManager().getInstrumentationInfo(
17147                     className, STOCK_PM_FLAGS);
17148                 ai = AppGlobals.getPackageManager().getApplicationInfo(
17149                         ii.targetPackage, STOCK_PM_FLAGS, userId);
17150             } catch (PackageManager.NameNotFoundException e) {
17151             } catch (RemoteException e) {
17152             }
17153             if (ii == null) {
17154                 reportStartInstrumentationFailure(watcher, className,
17155                         "Unable to find instrumentation info for: " + className);
17156                 return false;
17157             }
17158             if (ai == null) {
17159                 reportStartInstrumentationFailure(watcher, className,
17160                         "Unable to find instrumentation target package: " + ii.targetPackage);
17161                 return false;
17162             }
17163
17164             int match = mContext.getPackageManager().checkSignatures(
17165                     ii.targetPackage, ii.packageName);
17166             if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
17167                 String msg = "Permission Denial: starting instrumentation "
17168                         + className + " from pid="
17169                         + Binder.getCallingPid()
17170                         + ", uid=" + Binder.getCallingPid()
17171                         + " not allowed because package " + ii.packageName
17172                         + " does not have a signature matching the target "
17173                         + ii.targetPackage;
17174                 reportStartInstrumentationFailure(watcher, className, msg);
17175                 throw new SecurityException(msg);
17176             }
17177
17178             final long origId = Binder.clearCallingIdentity();
17179             // Instrumentation can kill and relaunch even persistent processes
17180             forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
17181                     "start instr");
17182             ProcessRecord app = addAppLocked(ai, false, abiOverride);
17183             app.instrumentationClass = className;
17184             app.instrumentationInfo = ai;
17185             app.instrumentationProfileFile = profileFile;
17186             app.instrumentationArguments = arguments;
17187             app.instrumentationWatcher = watcher;
17188             app.instrumentationUiAutomationConnection = uiAutomationConnection;
17189             app.instrumentationResultClass = className;
17190             Binder.restoreCallingIdentity(origId);
17191         }
17192
17193         return true;
17194     }
17195
17196     /**
17197      * Report errors that occur while attempting to start Instrumentation.  Always writes the
17198      * error to the logs, but if somebody is watching, send the report there too.  This enables
17199      * the "am" command to report errors with more information.
17200      *
17201      * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
17202      * @param cn The component name of the instrumentation.
17203      * @param report The error report.
17204      */
17205     private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
17206             ComponentName cn, String report) {
17207         Slog.w(TAG, report);
17208         try {
17209             if (watcher != null) {
17210                 Bundle results = new Bundle();
17211                 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
17212                 results.putString("Error", report);
17213                 watcher.instrumentationStatus(cn, -1, results);
17214             }
17215         } catch (RemoteException e) {
17216             Slog.w(TAG, e);
17217         }
17218     }
17219
17220     void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
17221         if (app.instrumentationWatcher != null) {
17222             try {
17223                 // NOTE:  IInstrumentationWatcher *must* be oneway here
17224                 app.instrumentationWatcher.instrumentationFinished(
17225                     app.instrumentationClass,
17226                     resultCode,
17227                     results);
17228             } catch (RemoteException e) {
17229             }
17230         }
17231
17232         // Can't call out of the system process with a lock held, so post a message.
17233         if (app.instrumentationUiAutomationConnection != null) {
17234             mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
17235                     app.instrumentationUiAutomationConnection).sendToTarget();
17236         }
17237
17238         app.instrumentationWatcher = null;
17239         app.instrumentationUiAutomationConnection = null;
17240         app.instrumentationClass = null;
17241         app.instrumentationInfo = null;
17242         app.instrumentationProfileFile = null;
17243         app.instrumentationArguments = null;
17244
17245         forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
17246                 "finished inst");
17247     }
17248
17249     public void finishInstrumentation(IApplicationThread target,
17250             int resultCode, Bundle results) {
17251         int userId = UserHandle.getCallingUserId();
17252         // Refuse possible leaked file descriptors
17253         if (results != null && results.hasFileDescriptors()) {
17254             throw new IllegalArgumentException("File descriptors passed in Intent");
17255         }
17256
17257         synchronized(this) {
17258             ProcessRecord app = getRecordForAppLocked(target);
17259             if (app == null) {
17260                 Slog.w(TAG, "finishInstrumentation: no app for " + target);
17261                 return;
17262             }
17263             final long origId = Binder.clearCallingIdentity();
17264             finishInstrumentationLocked(app, resultCode, results);
17265             Binder.restoreCallingIdentity(origId);
17266         }
17267     }
17268
17269     // =========================================================
17270     // CONFIGURATION
17271     // =========================================================
17272
17273     public ConfigurationInfo getDeviceConfigurationInfo() {
17274         ConfigurationInfo config = new ConfigurationInfo();
17275         synchronized (this) {
17276             config.reqTouchScreen = mConfiguration.touchscreen;
17277             config.reqKeyboardType = mConfiguration.keyboard;
17278             config.reqNavigation = mConfiguration.navigation;
17279             if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
17280                     || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
17281                 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
17282             }
17283             if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
17284                     && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
17285                 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
17286             }
17287             config.reqGlEsVersion = GL_ES_VERSION;
17288         }
17289         return config;
17290     }
17291
17292     ActivityStack getFocusedStack() {
17293         return mStackSupervisor.getFocusedStack();
17294     }
17295
17296     @Override
17297     public int getFocusedStackId() throws RemoteException {
17298         ActivityStack focusedStack = getFocusedStack();
17299         if (focusedStack != null) {
17300             return focusedStack.getStackId();
17301         }
17302         return -1;
17303     }
17304
17305     public Configuration getConfiguration() {
17306         Configuration ci;
17307         synchronized(this) {
17308             ci = new Configuration(mConfiguration);
17309             ci.userSetLocale = false;
17310         }
17311         return ci;
17312     }
17313
17314     public void updatePersistentConfiguration(Configuration values) {
17315         enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
17316                 "updateConfiguration()");
17317         enforceWriteSettingsPermission("updateConfiguration()");
17318         if (values == null) {
17319             throw new NullPointerException("Configuration must not be null");
17320         }
17321
17322         synchronized(this) {
17323             final long origId = Binder.clearCallingIdentity();
17324             updateConfigurationLocked(values, null, true, false);
17325             Binder.restoreCallingIdentity(origId);
17326         }
17327     }
17328
17329     private void enforceWriteSettingsPermission(String func) {
17330         int uid = Binder.getCallingUid();
17331         if (uid == Process.ROOT_UID) {
17332             return;
17333         }
17334
17335         if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
17336                 Settings.getPackageNameForUid(mContext, uid), false)) {
17337             return;
17338         }
17339
17340         String msg = "Permission Denial: " + func + " from pid="
17341                 + Binder.getCallingPid()
17342                 + ", uid=" + uid
17343                 + " requires " + android.Manifest.permission.WRITE_SETTINGS;
17344         Slog.w(TAG, msg);
17345         throw new SecurityException(msg);
17346     }
17347
17348     public void updateConfiguration(Configuration values) {
17349         enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
17350                 "updateConfiguration()");
17351
17352         synchronized(this) {
17353             if (values == null && mWindowManager != null) {
17354                 // sentinel: fetch the current configuration from the window manager
17355                 values = mWindowManager.computeNewConfiguration();
17356             }
17357
17358             if (mWindowManager != null) {
17359                 mProcessList.applyDisplaySize(mWindowManager);
17360             }
17361
17362             final long origId = Binder.clearCallingIdentity();
17363             if (values != null) {
17364                 Settings.System.clearConfiguration(values);
17365             }
17366             updateConfigurationLocked(values, null, false, false);
17367             Binder.restoreCallingIdentity(origId);
17368         }
17369     }
17370
17371     /**
17372      * Do either or both things: (1) change the current configuration, and (2)
17373      * make sure the given activity is running with the (now) current
17374      * configuration.  Returns true if the activity has been left running, or
17375      * false if <var>starting</var> is being destroyed to match the new
17376      * configuration.
17377      * @param persistent TODO
17378      */
17379     boolean updateConfigurationLocked(Configuration values,
17380             ActivityRecord starting, boolean persistent, boolean initLocale) {
17381         int changes = 0;
17382
17383         if (values != null) {
17384             Configuration newConfig = new Configuration(mConfiguration);
17385             changes = newConfig.updateFrom(values);
17386             if (changes != 0) {
17387                 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
17388                         "Updating configuration to: " + values);
17389
17390                 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
17391
17392                 if (!initLocale && values.locale != null && values.userSetLocale) {
17393                     final String languageTag = values.locale.toLanguageTag();
17394                     SystemProperties.set("persist.sys.locale", languageTag);
17395                     mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
17396                             values.locale));
17397                 }
17398
17399                 mConfigurationSeq++;
17400                 if (mConfigurationSeq <= 0) {
17401                     mConfigurationSeq = 1;
17402                 }
17403                 newConfig.seq = mConfigurationSeq;
17404                 mConfiguration = newConfig;
17405                 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
17406                 mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId);
17407                 //mUsageStatsService.noteStartConfig(newConfig);
17408
17409                 final Configuration configCopy = new Configuration(mConfiguration);
17410
17411                 // TODO: If our config changes, should we auto dismiss any currently
17412                 // showing dialogs?
17413                 mShowDialogs = shouldShowDialogs(newConfig);
17414
17415                 AttributeCache ac = AttributeCache.instance();
17416                 if (ac != null) {
17417                     ac.updateConfiguration(configCopy);
17418                 }
17419
17420                 // Make sure all resources in our process are updated
17421                 // right now, so that anyone who is going to retrieve
17422                 // resource values after we return will be sure to get
17423                 // the new ones.  This is especially important during
17424                 // boot, where the first config change needs to guarantee
17425                 // all resources have that config before following boot
17426                 // code is executed.
17427                 mSystemThread.applyConfigurationToResources(configCopy);
17428
17429                 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
17430                     Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
17431                     msg.obj = new Configuration(configCopy);
17432                     mHandler.sendMessage(msg);
17433                 }
17434
17435                 for (int i=mLruProcesses.size()-1; i>=0; i--) {
17436                     ProcessRecord app = mLruProcesses.get(i);
17437                     try {
17438                         if (app.thread != null) {
17439                             if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
17440                                     + app.processName + " new config " + mConfiguration);
17441                             app.thread.scheduleConfigurationChanged(configCopy);
17442                         }
17443                     } catch (Exception e) {
17444                     }
17445                 }
17446                 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
17447                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17448                         | Intent.FLAG_RECEIVER_REPLACE_PENDING
17449                         | Intent.FLAG_RECEIVER_FOREGROUND);
17450                 broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
17451                         null, AppOpsManager.OP_NONE, null, false, false,
17452                         MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17453                 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
17454                     intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
17455                     intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
17456                     if (!mProcessesReady) {
17457                         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17458                     }
17459                     broadcastIntentLocked(null, null, intent,
17460                             null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17461                             null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17462                 }
17463             }
17464         }
17465
17466         boolean kept = true;
17467         final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
17468         // mainStack is null during startup.
17469         if (mainStack != null) {
17470             if (changes != 0 && starting == null) {
17471                 // If the configuration changed, and the caller is not already
17472                 // in the process of starting an activity, then find the top
17473                 // activity to check if its configuration needs to change.
17474                 starting = mainStack.topRunningActivityLocked(null);
17475             }
17476
17477             if (starting != null) {
17478                 kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
17479                 // And we need to make sure at this point that all other activities
17480                 // are made visible with the correct configuration.
17481                 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
17482             }
17483         }
17484
17485         if (values != null && mWindowManager != null) {
17486             mWindowManager.setNewConfiguration(mConfiguration);
17487         }
17488
17489         return kept;
17490     }
17491
17492     /**
17493      * Decide based on the configuration whether we should shouw the ANR,
17494      * crash, etc dialogs.  The idea is that if there is no affordnace to
17495      * press the on-screen buttons, we shouldn't show the dialog.
17496      *
17497      * A thought: SystemUI might also want to get told about this, the Power
17498      * dialog / global actions also might want different behaviors.
17499      */
17500     private static final boolean shouldShowDialogs(Configuration config) {
17501         return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
17502                 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
17503                 && config.navigation == Configuration.NAVIGATION_NONAV);
17504     }
17505
17506     @Override
17507     public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
17508         synchronized (this) {
17509             ActivityRecord srec = ActivityRecord.forTokenLocked(token);
17510             if (srec != null) {
17511                 return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
17512             }
17513         }
17514         return false;
17515     }
17516
17517     public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
17518             Intent resultData) {
17519
17520         synchronized (this) {
17521             final ActivityRecord r = ActivityRecord.forTokenLocked(token);
17522             if (r != null) {
17523                 return r.task.stack.navigateUpToLocked(r, destIntent, resultCode, resultData);
17524             }
17525             return false;
17526         }
17527     }
17528
17529     public int getLaunchedFromUid(IBinder activityToken) {
17530         ActivityRecord srec;
17531         synchronized (this) {
17532             srec = ActivityRecord.forTokenLocked(activityToken);
17533         }
17534         if (srec == null) {
17535             return -1;
17536         }
17537         return srec.launchedFromUid;
17538     }
17539
17540     public String getLaunchedFromPackage(IBinder activityToken) {
17541         ActivityRecord srec;
17542         synchronized (this) {
17543             srec = ActivityRecord.forTokenLocked(activityToken);
17544         }
17545         if (srec == null) {
17546             return null;
17547         }
17548         return srec.launchedFromPackage;
17549     }
17550
17551     // =========================================================
17552     // LIFETIME MANAGEMENT
17553     // =========================================================
17554
17555     // Returns which broadcast queue the app is the current [or imminent] receiver
17556     // on, or 'null' if the app is not an active broadcast recipient.
17557     private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
17558         BroadcastRecord r = app.curReceiver;
17559         if (r != null) {
17560             return r.queue;
17561         }
17562
17563         // It's not the current receiver, but it might be starting up to become one
17564         synchronized (this) {
17565             for (BroadcastQueue queue : mBroadcastQueues) {
17566                 r = queue.mPendingBroadcast;
17567                 if (r != null && r.curApp == app) {
17568                     // found it; report which queue it's in
17569                     return queue;
17570                 }
17571             }
17572         }
17573
17574         return null;
17575     }
17576
17577     Association startAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
17578             ComponentName targetComponent, String targetProcess) {
17579         if (!mTrackingAssociations) {
17580             return null;
17581         }
17582         ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
17583                 = mAssociations.get(targetUid);
17584         if (components == null) {
17585             components = new ArrayMap<>();
17586             mAssociations.put(targetUid, components);
17587         }
17588         SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
17589         if (sourceUids == null) {
17590             sourceUids = new SparseArray<>();
17591             components.put(targetComponent, sourceUids);
17592         }
17593         ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
17594         if (sourceProcesses == null) {
17595             sourceProcesses = new ArrayMap<>();
17596             sourceUids.put(sourceUid, sourceProcesses);
17597         }
17598         Association ass = sourceProcesses.get(sourceProcess);
17599         if (ass == null) {
17600             ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
17601                     targetProcess);
17602             sourceProcesses.put(sourceProcess, ass);
17603         }
17604         ass.mCount++;
17605         ass.mNesting++;
17606         if (ass.mNesting == 1) {
17607             ass.mStartTime = SystemClock.uptimeMillis();
17608         }
17609         return ass;
17610     }
17611
17612     void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
17613             ComponentName targetComponent) {
17614         if (!mTrackingAssociations) {
17615             return;
17616         }
17617         ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
17618                 = mAssociations.get(targetUid);
17619         if (components == null) {
17620             return;
17621         }
17622         SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
17623         if (sourceUids == null) {
17624             return;
17625         }
17626         ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
17627         if (sourceProcesses == null) {
17628             return;
17629         }
17630         Association ass = sourceProcesses.get(sourceProcess);
17631         if (ass == null || ass.mNesting <= 0) {
17632             return;
17633         }
17634         ass.mNesting--;
17635         if (ass.mNesting == 0) {
17636             ass.mTime += SystemClock.uptimeMillis() - ass.mStartTime;
17637         }
17638     }
17639
17640     private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
17641             boolean doingAll, long now) {
17642         if (mAdjSeq == app.adjSeq) {
17643             // This adjustment has already been computed.
17644             return app.curRawAdj;
17645         }
17646
17647         if (app.thread == null) {
17648             app.adjSeq = mAdjSeq;
17649             app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17650             app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17651             return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
17652         }
17653
17654         app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
17655         app.adjSource = null;
17656         app.adjTarget = null;
17657         app.empty = false;
17658         app.cached = false;
17659
17660         final int activitiesSize = app.activities.size();
17661
17662         if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
17663             // The max adjustment doesn't allow this app to be anything
17664             // below foreground, so it is not worth doing work for it.
17665             app.adjType = "fixed";
17666             app.adjSeq = mAdjSeq;
17667             app.curRawAdj = app.maxAdj;
17668             app.foregroundActivities = false;
17669             app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
17670             app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
17671             // System processes can do UI, and when they do we want to have
17672             // them trim their memory after the user leaves the UI.  To
17673             // facilitate this, here we need to determine whether or not it
17674             // is currently showing UI.
17675             app.systemNoUi = true;
17676             if (app == TOP_APP) {
17677                 app.systemNoUi = false;
17678             } else if (activitiesSize > 0) {
17679                 for (int j = 0; j < activitiesSize; j++) {
17680                     final ActivityRecord r = app.activities.get(j);
17681                     if (r.visible) {
17682                         app.systemNoUi = false;
17683                     }
17684                 }
17685             }
17686             if (!app.systemNoUi) {
17687                 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
17688             }
17689             return (app.curAdj=app.maxAdj);
17690         }
17691
17692         app.systemNoUi = false;
17693
17694         final int PROCESS_STATE_TOP = mTopProcessState;
17695
17696         // Determine the importance of the process, starting with most
17697         // important to least, and assign an appropriate OOM adjustment.
17698         int adj;
17699         int schedGroup;
17700         int procState;
17701         boolean foregroundActivities = false;
17702         BroadcastQueue queue;
17703         if (app == TOP_APP) {
17704             // The last app on the list is the foreground app.
17705             adj = ProcessList.FOREGROUND_APP_ADJ;
17706             schedGroup = Process.THREAD_GROUP_DEFAULT;
17707             app.adjType = "top-activity";
17708             foregroundActivities = true;
17709             procState = PROCESS_STATE_TOP;
17710         } else if (app.instrumentationClass != null) {
17711             // Don't want to kill running instrumentation.
17712             adj = ProcessList.FOREGROUND_APP_ADJ;
17713             schedGroup = Process.THREAD_GROUP_DEFAULT;
17714             app.adjType = "instrumentation";
17715             procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
17716         } else if ((queue = isReceivingBroadcast(app)) != null) {
17717             // An app that is currently receiving a broadcast also
17718             // counts as being in the foreground for OOM killer purposes.
17719             // It's placed in a sched group based on the nature of the
17720             // broadcast as reflected by which queue it's active in.
17721             adj = ProcessList.FOREGROUND_APP_ADJ;
17722             schedGroup = (queue == mFgBroadcastQueue)
17723                     ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
17724             app.adjType = "broadcast";
17725             procState = ActivityManager.PROCESS_STATE_RECEIVER;
17726         } else if (app.executingServices.size() > 0) {
17727             // An app that is currently executing a service callback also
17728             // counts as being in the foreground.
17729             adj = ProcessList.FOREGROUND_APP_ADJ;
17730             schedGroup = app.execServicesFg ?
17731                     Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
17732             app.adjType = "exec-service";
17733             procState = ActivityManager.PROCESS_STATE_SERVICE;
17734             //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
17735         } else {
17736             // As far as we know the process is empty.  We may change our mind later.
17737             schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17738             // At this point we don't actually know the adjustment.  Use the cached adj
17739             // value that the caller wants us to.
17740             adj = cachedAdj;
17741             procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17742             app.cached = true;
17743             app.empty = true;
17744             app.adjType = "cch-empty";
17745         }
17746
17747         // Examine all activities if not already foreground.
17748         if (!foregroundActivities && activitiesSize > 0) {
17749             for (int j = 0; j < activitiesSize; j++) {
17750                 final ActivityRecord r = app.activities.get(j);
17751                 if (r.app != app) {
17752                     Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
17753                             + app + "?!? Using " + r.app + " instead.");
17754                     continue;
17755                 }
17756                 if (r.visible) {
17757                     // App has a visible activity; only upgrade adjustment.
17758                     if (adj > ProcessList.VISIBLE_APP_ADJ) {
17759                         adj = ProcessList.VISIBLE_APP_ADJ;
17760                         app.adjType = "visible";
17761                     }
17762                     if (procState > PROCESS_STATE_TOP) {
17763                         procState = PROCESS_STATE_TOP;
17764                     }
17765                     schedGroup = Process.THREAD_GROUP_DEFAULT;
17766                     app.cached = false;
17767                     app.empty = false;
17768                     foregroundActivities = true;
17769                     break;
17770                 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
17771                     if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17772                         adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17773                         app.adjType = "pausing";
17774                     }
17775                     if (procState > PROCESS_STATE_TOP) {
17776                         procState = PROCESS_STATE_TOP;
17777                     }
17778                     schedGroup = Process.THREAD_GROUP_DEFAULT;
17779                     app.cached = false;
17780                     app.empty = false;
17781                     foregroundActivities = true;
17782                 } else if (r.state == ActivityState.STOPPING) {
17783                     if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17784                         adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17785                         app.adjType = "stopping";
17786                     }
17787                     // For the process state, we will at this point consider the
17788                     // process to be cached.  It will be cached either as an activity
17789                     // or empty depending on whether the activity is finishing.  We do
17790                     // this so that we can treat the process as cached for purposes of
17791                     // memory trimming (determing current memory level, trim command to
17792                     // send to process) since there can be an arbitrary number of stopping
17793                     // processes and they should soon all go into the cached state.
17794                     if (!r.finishing) {
17795                         if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
17796                             procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
17797                         }
17798                     }
17799                     app.cached = false;
17800                     app.empty = false;
17801                     foregroundActivities = true;
17802                 } else {
17803                     if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
17804                         procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
17805                         app.adjType = "cch-act";
17806                     }
17807                 }
17808             }
17809         }
17810
17811         if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17812             if (app.foregroundServices) {
17813                 // The user is aware of this app, so make it visible.
17814                 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17815                 procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
17816                 app.cached = false;
17817                 app.adjType = "fg-service";
17818                 schedGroup = Process.THREAD_GROUP_DEFAULT;
17819             } else if (app.forcingToForeground != null) {
17820                 // The user is aware of this app, so make it visible.
17821                 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17822                 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17823                 app.cached = false;
17824                 app.adjType = "force-fg";
17825                 app.adjSource = app.forcingToForeground;
17826                 schedGroup = Process.THREAD_GROUP_DEFAULT;
17827             }
17828         }
17829
17830         if (app == mHeavyWeightProcess) {
17831             if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
17832                 // We don't want to kill the current heavy-weight process.
17833                 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
17834                 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17835                 app.cached = false;
17836                 app.adjType = "heavy";
17837             }
17838             if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
17839                 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
17840             }
17841         }
17842
17843         if (app == mHomeProcess) {
17844             if (adj > ProcessList.HOME_APP_ADJ) {
17845                 // This process is hosting what we currently consider to be the
17846                 // home app, so we don't want to let it go into the background.
17847                 adj = ProcessList.HOME_APP_ADJ;
17848                 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17849                 app.cached = false;
17850                 app.adjType = "home";
17851             }
17852             if (procState > ActivityManager.PROCESS_STATE_HOME) {
17853                 procState = ActivityManager.PROCESS_STATE_HOME;
17854             }
17855         }
17856
17857         if (app == mPreviousProcess && app.activities.size() > 0) {
17858             if (adj > ProcessList.PREVIOUS_APP_ADJ) {
17859                 // This was the previous process that showed UI to the user.
17860                 // We want to try to keep it around more aggressively, to give
17861                 // a good experience around switching between two apps.
17862                 adj = ProcessList.PREVIOUS_APP_ADJ;
17863                 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17864                 app.cached = false;
17865                 app.adjType = "previous";
17866             }
17867             if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
17868                 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
17869             }
17870         }
17871
17872         if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
17873                 + " reason=" + app.adjType);
17874
17875         // By default, we use the computed adjustment.  It may be changed if
17876         // there are applications dependent on our services or providers, but
17877         // this gives us a baseline and makes sure we don't get into an
17878         // infinite recursion.
17879         app.adjSeq = mAdjSeq;
17880         app.curRawAdj = adj;
17881         app.hasStartedServices = false;
17882
17883         if (mBackupTarget != null && app == mBackupTarget.app) {
17884             // If possible we want to avoid killing apps while they're being backed up
17885             if (adj > ProcessList.BACKUP_APP_ADJ) {
17886                 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
17887                 adj = ProcessList.BACKUP_APP_ADJ;
17888                 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
17889                     procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
17890                 }
17891                 app.adjType = "backup";
17892                 app.cached = false;
17893             }
17894             if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
17895                 procState = ActivityManager.PROCESS_STATE_BACKUP;
17896             }
17897         }
17898
17899         boolean mayBeTop = false;
17900
17901         for (int is = app.services.size()-1;
17902                 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17903                         || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17904                         || procState > ActivityManager.PROCESS_STATE_TOP);
17905                 is--) {
17906             ServiceRecord s = app.services.valueAt(is);
17907             if (s.startRequested) {
17908                 app.hasStartedServices = true;
17909                 if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
17910                     procState = ActivityManager.PROCESS_STATE_SERVICE;
17911                 }
17912                 if (app.hasShownUi && app != mHomeProcess) {
17913                     // If this process has shown some UI, let it immediately
17914                     // go to the LRU list because it may be pretty heavy with
17915                     // UI stuff.  We'll tag it with a label just to help
17916                     // debug and understand what is going on.
17917                     if (adj > ProcessList.SERVICE_ADJ) {
17918                         app.adjType = "cch-started-ui-services";
17919                     }
17920                 } else {
17921                     if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
17922                         // This service has seen some activity within
17923                         // recent memory, so we will keep its process ahead
17924                         // of the background processes.
17925                         if (adj > ProcessList.SERVICE_ADJ) {
17926                             adj = ProcessList.SERVICE_ADJ;
17927                             app.adjType = "started-services";
17928                             app.cached = false;
17929                         }
17930                     }
17931                     // If we have let the service slide into the background
17932                     // state, still have some text describing what it is doing
17933                     // even though the service no longer has an impact.
17934                     if (adj > ProcessList.SERVICE_ADJ) {
17935                         app.adjType = "cch-started-services";
17936                     }
17937                 }
17938             }
17939             for (int conni = s.connections.size()-1;
17940                     conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17941                             || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17942                             || procState > ActivityManager.PROCESS_STATE_TOP);
17943                     conni--) {
17944                 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
17945                 for (int i = 0;
17946                         i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
17947                                 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17948                                 || procState > ActivityManager.PROCESS_STATE_TOP);
17949                         i++) {
17950                     // XXX should compute this based on the max of
17951                     // all connected clients.
17952                     ConnectionRecord cr = clist.get(i);
17953                     if (cr.binding.client == app) {
17954                         // Binding to ourself is not interesting.
17955                         continue;
17956                     }
17957                     if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
17958                         ProcessRecord client = cr.binding.client;
17959                         int clientAdj = computeOomAdjLocked(client, cachedAdj,
17960                                 TOP_APP, doingAll, now);
17961                         int clientProcState = client.curProcState;
17962                         if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
17963                             // If the other app is cached for any reason, for purposes here
17964                             // we are going to consider it empty.  The specific cached state
17965                             // doesn't propagate except under certain conditions.
17966                             clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17967                         }
17968                         String adjType = null;
17969                         if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
17970                             // Not doing bind OOM management, so treat
17971                             // this guy more like a started service.
17972                             if (app.hasShownUi && app != mHomeProcess) {
17973                                 // If this process has shown some UI, let it immediately
17974                                 // go to the LRU list because it may be pretty heavy with
17975                                 // UI stuff.  We'll tag it with a label just to help
17976                                 // debug and understand what is going on.
17977                                 if (adj > clientAdj) {
17978                                     adjType = "cch-bound-ui-services";
17979                                 }
17980                                 app.cached = false;
17981                                 clientAdj = adj;
17982                                 clientProcState = procState;
17983                             } else {
17984                                 if (now >= (s.lastActivity
17985                                         + ActiveServices.MAX_SERVICE_INACTIVITY)) {
17986                                     // This service has not seen activity within
17987                                     // recent memory, so allow it to drop to the
17988                                     // LRU list if there is no other reason to keep
17989                                     // it around.  We'll also tag it with a label just
17990                                     // to help debug and undertand what is going on.
17991                                     if (adj > clientAdj) {
17992                                         adjType = "cch-bound-services";
17993                                     }
17994                                     clientAdj = adj;
17995                                 }
17996                             }
17997                         }
17998                         if (adj > clientAdj) {
17999                             // If this process has recently shown UI, and
18000                             // the process that is binding to it is less
18001                             // important than being visible, then we don't
18002                             // care about the binding as much as we care
18003                             // about letting this process get into the LRU
18004                             // list to be killed and restarted if needed for
18005                             // memory.
18006                             if (app.hasShownUi && app != mHomeProcess
18007                                     && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18008                                 adjType = "cch-bound-ui-services";
18009                             } else {
18010                                 if ((cr.flags&(Context.BIND_ABOVE_CLIENT
18011                                         |Context.BIND_IMPORTANT)) != 0) {
18012                                     adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
18013                                             ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
18014                                 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
18015                                         && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
18016                                         && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18017                                     adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18018                                 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
18019                                     adj = clientAdj;
18020                                 } else {
18021                                     if (adj > ProcessList.VISIBLE_APP_ADJ) {
18022                                         adj = ProcessList.VISIBLE_APP_ADJ;
18023                                     }
18024                                 }
18025                                 if (!client.cached) {
18026                                     app.cached = false;
18027                                 }
18028                                 adjType = "service";
18029                             }
18030                         }
18031                         if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
18032                             if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
18033                                 schedGroup = Process.THREAD_GROUP_DEFAULT;
18034                             }
18035                             if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
18036                                 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
18037                                     // Special handling of clients who are in the top state.
18038                                     // We *may* want to consider this process to be in the
18039                                     // top state as well, but only if there is not another
18040                                     // reason for it to be running.  Being on the top is a
18041                                     // special state, meaning you are specifically running
18042                                     // for the current top app.  If the process is already
18043                                     // running in the background for some other reason, it
18044                                     // is more important to continue considering it to be
18045                                     // in the background state.
18046                                     mayBeTop = true;
18047                                     clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18048                                 } else {
18049                                     // Special handling for above-top states (persistent
18050                                     // processes).  These should not bring the current process
18051                                     // into the top state, since they are not on top.  Instead
18052                                     // give them the best state after that.
18053                                     if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
18054                                         clientProcState =
18055                                                 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18056                                     } else if (mWakefulness
18057                                                     == PowerManagerInternal.WAKEFULNESS_AWAKE &&
18058                                             (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
18059                                                     != 0) {
18060                                         clientProcState =
18061                                                 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18062                                     } else {
18063                                         clientProcState =
18064                                                 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18065                                     }
18066                                 }
18067                             }
18068                         } else {
18069                             if (clientProcState <
18070                                     ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
18071                                 clientProcState =
18072                                         ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
18073                             }
18074                         }
18075                         if (procState > clientProcState) {
18076                             procState = clientProcState;
18077                         }
18078                         if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
18079                                 && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
18080                             app.pendingUiClean = true;
18081                         }
18082                         if (adjType != null) {
18083                             app.adjType = adjType;
18084                             app.adjTypeCode = ActivityManager.RunningAppProcessInfo
18085                                     .REASON_SERVICE_IN_USE;
18086                             app.adjSource = cr.binding.client;
18087                             app.adjSourceProcState = clientProcState;
18088                             app.adjTarget = s.name;
18089                         }
18090                     }
18091                     if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
18092                         app.treatLikeActivity = true;
18093                     }
18094                     final ActivityRecord a = cr.activity;
18095                     if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
18096                         if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
18097                                 (a.visible || a.state == ActivityState.RESUMED
18098                                  || a.state == ActivityState.PAUSING)) {
18099                             adj = ProcessList.FOREGROUND_APP_ADJ;
18100                             if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
18101                                 schedGroup = Process.THREAD_GROUP_DEFAULT;
18102                             }
18103                             app.cached = false;
18104                             app.adjType = "service";
18105                             app.adjTypeCode = ActivityManager.RunningAppProcessInfo
18106                                     .REASON_SERVICE_IN_USE;
18107                             app.adjSource = a;
18108                             app.adjSourceProcState = procState;
18109                             app.adjTarget = s.name;
18110                         }
18111                     }
18112                 }
18113             }
18114         }
18115
18116         for (int provi = app.pubProviders.size()-1;
18117                 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18118                         || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
18119                         || procState > ActivityManager.PROCESS_STATE_TOP);
18120                 provi--) {
18121             ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
18122             for (int i = cpr.connections.size()-1;
18123                     i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18124                             || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
18125                             || procState > ActivityManager.PROCESS_STATE_TOP);
18126                     i--) {
18127                 ContentProviderConnection conn = cpr.connections.get(i);
18128                 ProcessRecord client = conn.client;
18129                 if (client == app) {
18130                     // Being our own client is not interesting.
18131                     continue;
18132                 }
18133                 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
18134                 int clientProcState = client.curProcState;
18135                 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
18136                     // If the other app is cached for any reason, for purposes here
18137                     // we are going to consider it empty.
18138                     clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18139                 }
18140                 if (adj > clientAdj) {
18141                     if (app.hasShownUi && app != mHomeProcess
18142                             && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18143                         app.adjType = "cch-ui-provider";
18144                     } else {
18145                         adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
18146                                 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
18147                         app.adjType = "provider";
18148                     }
18149                     app.cached &= client.cached;
18150                     app.adjTypeCode = ActivityManager.RunningAppProcessInfo
18151                             .REASON_PROVIDER_IN_USE;
18152                     app.adjSource = client;
18153                     app.adjSourceProcState = clientProcState;
18154                     app.adjTarget = cpr.name;
18155                 }
18156                 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
18157                     if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
18158                         // Special handling of clients who are in the top state.
18159                         // We *may* want to consider this process to be in the
18160                         // top state as well, but only if there is not another
18161                         // reason for it to be running.  Being on the top is a
18162                         // special state, meaning you are specifically running
18163                         // for the current top app.  If the process is already
18164                         // running in the background for some other reason, it
18165                         // is more important to continue considering it to be
18166                         // in the background state.
18167                         mayBeTop = true;
18168                         clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18169                     } else {
18170                         // Special handling for above-top states (persistent
18171                         // processes).  These should not bring the current process
18172                         // into the top state, since they are not on top.  Instead
18173                         // give them the best state after that.
18174                         clientProcState =
18175                                 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18176                     }
18177                 }
18178                 if (procState > clientProcState) {
18179                     procState = clientProcState;
18180                 }
18181                 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
18182                     schedGroup = Process.THREAD_GROUP_DEFAULT;
18183                 }
18184             }
18185             // If the provider has external (non-framework) process
18186             // dependencies, ensure that its adjustment is at least
18187             // FOREGROUND_APP_ADJ.
18188             if (cpr.hasExternalProcessHandles()) {
18189                 if (adj > ProcessList.FOREGROUND_APP_ADJ) {
18190                     adj = ProcessList.FOREGROUND_APP_ADJ;
18191                     schedGroup = Process.THREAD_GROUP_DEFAULT;
18192                     app.cached = false;
18193                     app.adjType = "provider";
18194                     app.adjTarget = cpr.name;
18195                 }
18196                 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
18197                     procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18198                 }
18199             }
18200         }
18201
18202         if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
18203             // A client of one of our services or providers is in the top state.  We
18204             // *may* want to be in the top state, but not if we are already running in
18205             // the background for some other reason.  For the decision here, we are going
18206             // to pick out a few specific states that we want to remain in when a client
18207             // is top (states that tend to be longer-term) and otherwise allow it to go
18208             // to the top state.
18209             switch (procState) {
18210                 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
18211                 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
18212                 case ActivityManager.PROCESS_STATE_SERVICE:
18213                     // These all are longer-term states, so pull them up to the top
18214                     // of the background states, but not all the way to the top state.
18215                     procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18216                     break;
18217                 default:
18218                     // Otherwise, top is a better choice, so take it.
18219                     procState = ActivityManager.PROCESS_STATE_TOP;
18220                     break;
18221             }
18222         }
18223
18224         if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
18225             if (app.hasClientActivities) {
18226                 // This is a cached process, but with client activities.  Mark it so.
18227                 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
18228                 app.adjType = "cch-client-act";
18229             } else if (app.treatLikeActivity) {
18230                 // This is a cached process, but somebody wants us to treat it like it has
18231                 // an activity, okay!
18232                 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
18233                 app.adjType = "cch-as-act";
18234             }
18235         }
18236
18237         if (adj == ProcessList.SERVICE_ADJ) {
18238             if (doingAll) {
18239                 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
18240                 mNewNumServiceProcs++;
18241                 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
18242                 if (!app.serviceb) {
18243                     // This service isn't far enough down on the LRU list to
18244                     // normally be a B service, but if we are low on RAM and it
18245                     // is large we want to force it down since we would prefer to
18246                     // keep launcher over it.
18247                     if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
18248                             && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
18249                         app.serviceHighRam = true;
18250                         app.serviceb = true;
18251                         //Slog.i(TAG, "ADJ " + app + " high ram!");
18252                     } else {
18253                         mNewNumAServiceProcs++;
18254                         //Slog.i(TAG, "ADJ " + app + " not high ram!");
18255                     }
18256                 } else {
18257                     app.serviceHighRam = false;
18258                 }
18259             }
18260             if (app.serviceb) {
18261                 adj = ProcessList.SERVICE_B_ADJ;
18262             }
18263         }
18264
18265         app.curRawAdj = adj;
18266
18267         //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
18268         //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
18269         if (adj > app.maxAdj) {
18270             adj = app.maxAdj;
18271             if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
18272                 schedGroup = Process.THREAD_GROUP_DEFAULT;
18273             }
18274         }
18275
18276         // Do final modification to adj.  Everything we do between here and applying
18277         // the final setAdj must be done in this function, because we will also use
18278         // it when computing the final cached adj later.  Note that we don't need to
18279         // worry about this for max adj above, since max adj will always be used to
18280         // keep it out of the cached vaues.
18281         app.curAdj = app.modifyRawOomAdj(adj);
18282         app.curSchedGroup = schedGroup;
18283         app.curProcState = procState;
18284         app.foregroundActivities = foregroundActivities;
18285
18286         return app.curRawAdj;
18287     }
18288
18289     /**
18290      * Record new PSS sample for a process.
18291      */
18292     void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long now) {
18293         EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024);
18294         proc.lastPssTime = now;
18295         proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
18296         if (DEBUG_PSS) Slog.d(TAG_PSS,
18297                 "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
18298                 + " state=" + ProcessList.makeProcStateString(procState));
18299         if (proc.initialIdlePss == 0) {
18300             proc.initialIdlePss = pss;
18301         }
18302         proc.lastPss = pss;
18303         if (procState >= ActivityManager.PROCESS_STATE_HOME) {
18304             proc.lastCachedPss = pss;
18305         }
18306
18307         final SparseArray<Pair<Long, String>> watchUids
18308                 = mMemWatchProcesses.getMap().get(proc.processName);
18309         Long check = null;
18310         if (watchUids != null) {
18311             Pair<Long, String> val = watchUids.get(proc.uid);
18312             if (val == null) {
18313                 val = watchUids.get(0);
18314             }
18315             if (val != null) {
18316                 check = val.first;
18317             }
18318         }
18319         if (check != null) {
18320             if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
18321                 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
18322                 if (!isDebuggable) {
18323                     if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
18324                         isDebuggable = true;
18325                     }
18326                 }
18327                 if (isDebuggable) {
18328                     Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
18329                     final ProcessRecord myProc = proc;
18330                     final File heapdumpFile = DumpHeapProvider.getJavaFile();
18331                     mMemWatchDumpProcName = proc.processName;
18332                     mMemWatchDumpFile = heapdumpFile.toString();
18333                     mMemWatchDumpPid = proc.pid;
18334                     mMemWatchDumpUid = proc.uid;
18335                     BackgroundThread.getHandler().post(new Runnable() {
18336                         @Override
18337                         public void run() {
18338                             revokeUriPermission(ActivityThread.currentActivityThread()
18339                                             .getApplicationThread(),
18340                                     DumpHeapActivity.JAVA_URI,
18341                                     Intent.FLAG_GRANT_READ_URI_PERMISSION
18342                                             | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
18343                                     UserHandle.myUserId());
18344                             ParcelFileDescriptor fd = null;
18345                             try {
18346                                 heapdumpFile.delete();
18347                                 fd = ParcelFileDescriptor.open(heapdumpFile,
18348                                         ParcelFileDescriptor.MODE_CREATE |
18349                                                 ParcelFileDescriptor.MODE_TRUNCATE |
18350                                                 ParcelFileDescriptor.MODE_WRITE_ONLY |
18351                                                 ParcelFileDescriptor.MODE_APPEND);
18352                                 IApplicationThread thread = myProc.thread;
18353                                 if (thread != null) {
18354                                     try {
18355                                         if (DEBUG_PSS) Slog.d(TAG_PSS,
18356                                                 "Requesting dump heap from "
18357                                                 + myProc + " to " + heapdumpFile);
18358                                         thread.dumpHeap(true, heapdumpFile.toString(), fd);
18359                                     } catch (RemoteException e) {
18360                                     }
18361                                 }
18362                             } catch (FileNotFoundException e) {
18363                                 e.printStackTrace();
18364                             } finally {
18365                                 if (fd != null) {
18366                                     try {
18367                                         fd.close();
18368                                     } catch (IOException e) {
18369                                     }
18370                                 }
18371                             }
18372                         }
18373                     });
18374                 } else {
18375                     Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
18376                             + ", but debugging not enabled");
18377                 }
18378             }
18379         }
18380     }
18381
18382     /**
18383      * Schedule PSS collection of a process.
18384      */
18385     void requestPssLocked(ProcessRecord proc, int procState) {
18386         if (mPendingPssProcesses.contains(proc)) {
18387             return;
18388         }
18389         if (mPendingPssProcesses.size() == 0) {
18390             mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
18391         }
18392         if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
18393         proc.pssProcState = procState;
18394         mPendingPssProcesses.add(proc);
18395     }
18396
18397     /**
18398      * Schedule PSS collection of all processes.
18399      */
18400     void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
18401         if (!always) {
18402             if (now < (mLastFullPssTime +
18403                     (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
18404                 return;
18405             }
18406         }
18407         if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
18408         mLastFullPssTime = now;
18409         mFullPssPending = true;
18410         mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
18411         mPendingPssProcesses.clear();
18412         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
18413             ProcessRecord app = mLruProcesses.get(i);
18414             if (app.thread == null
18415                     || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
18416                 continue;
18417             }
18418             if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
18419                 app.pssProcState = app.setProcState;
18420                 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
18421                         mTestPssMode, isSleeping(), now);
18422                 mPendingPssProcesses.add(app);
18423             }
18424         }
18425         mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
18426     }
18427
18428     public void setTestPssMode(boolean enabled) {
18429         synchronized (this) {
18430             mTestPssMode = enabled;
18431             if (enabled) {
18432                 // Whenever we enable the mode, we want to take a snapshot all of current
18433                 // process mem use.
18434                 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
18435             }
18436         }
18437     }
18438
18439     /**
18440      * Ask a given process to GC right now.
18441      */
18442     final void performAppGcLocked(ProcessRecord app) {
18443         try {
18444             app.lastRequestedGc = SystemClock.uptimeMillis();
18445             if (app.thread != null) {
18446                 if (app.reportLowMemory) {
18447                     app.reportLowMemory = false;
18448                     app.thread.scheduleLowMemory();
18449                 } else {
18450                     app.thread.processInBackground();
18451                 }
18452             }
18453         } catch (Exception e) {
18454             // whatever.
18455         }
18456     }
18457
18458     /**
18459      * Returns true if things are idle enough to perform GCs.
18460      */
18461     private final boolean canGcNowLocked() {
18462         boolean processingBroadcasts = false;
18463         for (BroadcastQueue q : mBroadcastQueues) {
18464             if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
18465                 processingBroadcasts = true;
18466             }
18467         }
18468         return !processingBroadcasts
18469                 && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
18470     }
18471
18472     /**
18473      * Perform GCs on all processes that are waiting for it, but only
18474      * if things are idle.
18475      */
18476     final void performAppGcsLocked() {
18477         final int N = mProcessesToGc.size();
18478         if (N <= 0) {
18479             return;
18480         }
18481         if (canGcNowLocked()) {
18482             while (mProcessesToGc.size() > 0) {
18483                 ProcessRecord proc = mProcessesToGc.remove(0);
18484                 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
18485                     if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
18486                             <= SystemClock.uptimeMillis()) {
18487                         // To avoid spamming the system, we will GC processes one
18488                         // at a time, waiting a few seconds between each.
18489                         performAppGcLocked(proc);
18490                         scheduleAppGcsLocked();
18491                         return;
18492                     } else {
18493                         // It hasn't been long enough since we last GCed this
18494                         // process...  put it in the list to wait for its time.
18495                         addProcessToGcListLocked(proc);
18496                         break;
18497                     }
18498                 }
18499             }
18500
18501             scheduleAppGcsLocked();
18502         }
18503     }
18504
18505     /**
18506      * If all looks good, perform GCs on all processes waiting for them.
18507      */
18508     final void performAppGcsIfAppropriateLocked() {
18509         if (canGcNowLocked()) {
18510             performAppGcsLocked();
18511             return;
18512         }
18513         // Still not idle, wait some more.
18514         scheduleAppGcsLocked();
18515     }
18516
18517     /**
18518      * Schedule the execution of all pending app GCs.
18519      */
18520     final void scheduleAppGcsLocked() {
18521         mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
18522
18523         if (mProcessesToGc.size() > 0) {
18524             // Schedule a GC for the time to the next process.
18525             ProcessRecord proc = mProcessesToGc.get(0);
18526             Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
18527
18528             long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
18529             long now = SystemClock.uptimeMillis();
18530             if (when < (now+GC_TIMEOUT)) {
18531                 when = now + GC_TIMEOUT;
18532             }
18533             mHandler.sendMessageAtTime(msg, when);
18534         }
18535     }
18536
18537     /**
18538      * Add a process to the array of processes waiting to be GCed.  Keeps the
18539      * list in sorted order by the last GC time.  The process can't already be
18540      * on the list.
18541      */
18542     final void addProcessToGcListLocked(ProcessRecord proc) {
18543         boolean added = false;
18544         for (int i=mProcessesToGc.size()-1; i>=0; i--) {
18545             if (mProcessesToGc.get(i).lastRequestedGc <
18546                     proc.lastRequestedGc) {
18547                 added = true;
18548                 mProcessesToGc.add(i+1, proc);
18549                 break;
18550             }
18551         }
18552         if (!added) {
18553             mProcessesToGc.add(0, proc);
18554         }
18555     }
18556
18557     /**
18558      * Set up to ask a process to GC itself.  This will either do it
18559      * immediately, or put it on the list of processes to gc the next
18560      * time things are idle.
18561      */
18562     final void scheduleAppGcLocked(ProcessRecord app) {
18563         long now = SystemClock.uptimeMillis();
18564         if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
18565             return;
18566         }
18567         if (!mProcessesToGc.contains(app)) {
18568             addProcessToGcListLocked(app);
18569             scheduleAppGcsLocked();
18570         }
18571     }
18572
18573     final void checkExcessivePowerUsageLocked(boolean doKills) {
18574         updateCpuStatsNow();
18575
18576         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
18577         boolean doWakeKills = doKills;
18578         boolean doCpuKills = doKills;
18579         if (mLastPowerCheckRealtime == 0) {
18580             doWakeKills = false;
18581         }
18582         if (mLastPowerCheckUptime == 0) {
18583             doCpuKills = false;
18584         }
18585         if (stats.isScreenOn()) {
18586             doWakeKills = false;
18587         }
18588         final long curRealtime = SystemClock.elapsedRealtime();
18589         final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
18590         final long curUptime = SystemClock.uptimeMillis();
18591         final long uptimeSince = curUptime - mLastPowerCheckUptime;
18592         mLastPowerCheckRealtime = curRealtime;
18593         mLastPowerCheckUptime = curUptime;
18594         if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
18595             doWakeKills = false;
18596         }
18597         if (uptimeSince < CPU_MIN_CHECK_DURATION) {
18598             doCpuKills = false;
18599         }
18600         int i = mLruProcesses.size();
18601         while (i > 0) {
18602             i--;
18603             ProcessRecord app = mLruProcesses.get(i);
18604             if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
18605                 long wtime;
18606                 synchronized (stats) {
18607                     wtime = stats.getProcessWakeTime(app.info.uid,
18608                             app.pid, curRealtime);
18609                 }
18610                 long wtimeUsed = wtime - app.lastWakeTime;
18611                 long cputimeUsed = app.curCpuTime - app.lastCpuTime;
18612                 if (DEBUG_POWER) {
18613                     StringBuilder sb = new StringBuilder(128);
18614                     sb.append("Wake for ");
18615                     app.toShortString(sb);
18616                     sb.append(": over ");
18617                     TimeUtils.formatDuration(realtimeSince, sb);
18618                     sb.append(" used ");
18619                     TimeUtils.formatDuration(wtimeUsed, sb);
18620                     sb.append(" (");
18621                     sb.append((wtimeUsed*100)/realtimeSince);
18622                     sb.append("%)");
18623                     Slog.i(TAG_POWER, sb.toString());
18624                     sb.setLength(0);
18625                     sb.append("CPU for ");
18626                     app.toShortString(sb);
18627                     sb.append(": over ");
18628                     TimeUtils.formatDuration(uptimeSince, sb);
18629                     sb.append(" used ");
18630                     TimeUtils.formatDuration(cputimeUsed, sb);
18631                     sb.append(" (");
18632                     sb.append((cputimeUsed*100)/uptimeSince);
18633                     sb.append("%)");
18634                     Slog.i(TAG_POWER, sb.toString());
18635                 }
18636                 // If a process has held a wake lock for more
18637                 // than 50% of the time during this period,
18638                 // that sounds bad.  Kill!
18639                 if (doWakeKills && realtimeSince > 0
18640                         && ((wtimeUsed*100)/realtimeSince) >= 50) {
18641                     synchronized (stats) {
18642                         stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
18643                                 realtimeSince, wtimeUsed);
18644                     }
18645                     app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
18646                     app.baseProcessTracker.reportExcessiveWake(app.pkgList);
18647                 } else if (doCpuKills && uptimeSince > 0
18648                         && ((cputimeUsed*100)/uptimeSince) >= 25) {
18649                     synchronized (stats) {
18650                         stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
18651                                 uptimeSince, cputimeUsed);
18652                     }
18653                     app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
18654                     app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
18655                 } else {
18656                     app.lastWakeTime = wtime;
18657                     app.lastCpuTime = app.curCpuTime;
18658                 }
18659             }
18660         }
18661     }
18662
18663     private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
18664             long nowElapsed) {
18665         boolean success = true;
18666
18667         if (app.curRawAdj != app.setRawAdj) {
18668             app.setRawAdj = app.curRawAdj;
18669         }
18670
18671         int changes = 0;
18672
18673         if (app.curAdj != app.setAdj) {
18674             ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
18675             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
18676                     "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
18677                     + app.adjType);
18678             app.setAdj = app.curAdj;
18679         }
18680
18681         if (app.setSchedGroup != app.curSchedGroup) {
18682             app.setSchedGroup = app.curSchedGroup;
18683             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
18684                     "Setting process group of " + app.processName
18685                     + " to " + app.curSchedGroup);
18686             if (app.waitingToKill != null && app.curReceiver == null
18687                     && app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
18688                 app.kill(app.waitingToKill, true);
18689                 success = false;
18690             } else {
18691                 if (true) {
18692                     long oldId = Binder.clearCallingIdentity();
18693                     try {
18694                         Process.setProcessGroup(app.pid, app.curSchedGroup);
18695                     } catch (Exception e) {
18696                         Slog.w(TAG, "Failed setting process group of " + app.pid
18697                                 + " to " + app.curSchedGroup);
18698                         e.printStackTrace();
18699                     } finally {
18700                         Binder.restoreCallingIdentity(oldId);
18701                     }
18702                 } else {
18703                     if (app.thread != null) {
18704                         try {
18705                             app.thread.setSchedulingGroup(app.curSchedGroup);
18706                         } catch (RemoteException e) {
18707                         }
18708                     }
18709                 }
18710                 Process.setSwappiness(app.pid,
18711                         app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
18712             }
18713         }
18714         if (app.repForegroundActivities != app.foregroundActivities) {
18715             app.repForegroundActivities = app.foregroundActivities;
18716             changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
18717         }
18718         if (app.repProcState != app.curProcState) {
18719             app.repProcState = app.curProcState;
18720             changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
18721             if (app.thread != null) {
18722                 try {
18723                     if (false) {
18724                         //RuntimeException h = new RuntimeException("here");
18725                         Slog.i(TAG, "Sending new process state " + app.repProcState
18726                                 + " to " + app /*, h*/);
18727                     }
18728                     app.thread.setProcessState(app.repProcState);
18729                 } catch (RemoteException e) {
18730                 }
18731             }
18732         }
18733         if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
18734                 || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
18735             if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
18736                 // Experimental code to more aggressively collect pss while
18737                 // running test...  the problem is that this tends to collect
18738                 // the data right when a process is transitioning between process
18739                 // states, which well tend to give noisy data.
18740                 long start = SystemClock.uptimeMillis();
18741                 long pss = Debug.getPss(app.pid, mTmpLong, null);
18742                 recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], now);
18743                 mPendingPssProcesses.remove(app);
18744                 Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
18745                         + " to " + app.curProcState + ": "
18746                         + (SystemClock.uptimeMillis()-start) + "ms");
18747             }
18748             app.lastStateTime = now;
18749             app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
18750                     mTestPssMode, isSleeping(), now);
18751             if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
18752                     + ProcessList.makeProcStateString(app.setProcState) + " to "
18753                     + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
18754                     + (app.nextPssTime-now) + ": " + app);
18755         } else {
18756             if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
18757                     && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
18758                     mTestPssMode)))) {
18759                 requestPssLocked(app, app.setProcState);
18760                 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
18761                         mTestPssMode, isSleeping(), now);
18762             } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
18763                     "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
18764         }
18765         if (app.setProcState != app.curProcState) {
18766             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
18767                     "Proc state change of " + app.processName
18768                             + " to " + app.curProcState);
18769             boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
18770             boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
18771             if (setImportant && !curImportant) {
18772                 // This app is no longer something we consider important enough to allow to
18773                 // use arbitrary amounts of battery power.  Note
18774                 // its current wake lock time to later know to kill it if
18775                 // it is not behaving well.
18776                 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
18777                 synchronized (stats) {
18778                     app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
18779                             app.pid, nowElapsed);
18780                 }
18781                 app.lastCpuTime = app.curCpuTime;
18782
18783             }
18784             // Inform UsageStats of important process state change
18785             // Must be called before updating setProcState
18786             maybeUpdateUsageStatsLocked(app, nowElapsed);
18787
18788             app.setProcState = app.curProcState;
18789             if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
18790                 app.notCachedSinceIdle = false;
18791             }
18792             if (!doingAll) {
18793                 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
18794             } else {
18795                 app.procStateChanged = true;
18796             }
18797         } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
18798                 > USAGE_STATS_INTERACTION_INTERVAL) {
18799             // For apps that sit around for a long time in the interactive state, we need
18800             // to report this at least once a day so they don't go idle.
18801             maybeUpdateUsageStatsLocked(app, nowElapsed);
18802         }
18803
18804         if (changes != 0) {
18805             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18806                     "Changes in " + app + ": " + changes);
18807             int i = mPendingProcessChanges.size()-1;
18808             ProcessChangeItem item = null;
18809             while (i >= 0) {
18810                 item = mPendingProcessChanges.get(i);
18811                 if (item.pid == app.pid) {
18812                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18813                             "Re-using existing item: " + item);
18814                     break;
18815                 }
18816                 i--;
18817             }
18818             if (i < 0) {
18819                 // No existing item in pending changes; need a new one.
18820                 final int NA = mAvailProcessChanges.size();
18821                 if (NA > 0) {
18822                     item = mAvailProcessChanges.remove(NA-1);
18823                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18824                             "Retrieving available item: " + item);
18825                 } else {
18826                     item = new ProcessChangeItem();
18827                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18828                             "Allocating new item: " + item);
18829                 }
18830                 item.changes = 0;
18831                 item.pid = app.pid;
18832                 item.uid = app.info.uid;
18833                 if (mPendingProcessChanges.size() == 0) {
18834                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18835                             "*** Enqueueing dispatch processes changed!");
18836                     mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
18837                 }
18838                 mPendingProcessChanges.add(item);
18839             }
18840             item.changes |= changes;
18841             item.processState = app.repProcState;
18842             item.foregroundActivities = app.repForegroundActivities;
18843             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18844                     "Item " + Integer.toHexString(System.identityHashCode(item))
18845                     + " " + app.toShortString() + ": changes=" + item.changes
18846                     + " procState=" + item.processState
18847                     + " foreground=" + item.foregroundActivities
18848                     + " type=" + app.adjType + " source=" + app.adjSource
18849                     + " target=" + app.adjTarget);
18850         }
18851
18852         return success;
18853     }
18854
18855     private final void enqueueUidChangeLocked(UidRecord uidRec, boolean gone) {
18856         if (uidRec.pendingChange == null) {
18857             if (mPendingUidChanges.size() == 0) {
18858                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
18859                         "*** Enqueueing dispatch uid changed!");
18860                 mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_MSG).sendToTarget();
18861             }
18862             final int NA = mAvailUidChanges.size();
18863             if (NA > 0) {
18864                 uidRec.pendingChange = mAvailUidChanges.remove(NA-1);
18865                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
18866                         "Retrieving available item: " + uidRec.pendingChange);
18867             } else {
18868                 uidRec.pendingChange = new UidRecord.ChangeItem();
18869                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
18870                         "Allocating new item: " + uidRec.pendingChange);
18871             }
18872             uidRec.pendingChange.uidRecord = uidRec;
18873             uidRec.pendingChange.uid = uidRec.uid;
18874             mPendingUidChanges.add(uidRec.pendingChange);
18875         }
18876         uidRec.pendingChange.gone = gone;
18877         uidRec.pendingChange.processState = uidRec.setProcState;
18878     }
18879
18880     private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
18881             String authority) {
18882         if (app == null) return;
18883         if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
18884             UserState userState = mStartedUsers.get(app.userId);
18885             if (userState == null) return;
18886             final long now = SystemClock.elapsedRealtime();
18887             Long lastReported = userState.mProviderLastReportedFg.get(authority);
18888             if (lastReported == null || lastReported < now - 60 * 1000L) {
18889                 mUsageStatsService.reportContentProviderUsage(
18890                         authority, providerPkgName, app.userId);
18891                 userState.mProviderLastReportedFg.put(authority, now);
18892             }
18893         }
18894     }
18895
18896     private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
18897         if (DEBUG_USAGE_STATS) {
18898             Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
18899                     + "] state changes: old = " + app.setProcState + ", new = "
18900                     + app.curProcState);
18901         }
18902         if (mUsageStatsService == null) {
18903             return;
18904         }
18905         boolean isInteraction;
18906         // To avoid some abuse patterns, we are going to be careful about what we consider
18907         // to be an app interaction.  Being the top activity doesn't count while the display
18908         // is sleeping, nor do short foreground services.
18909         if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
18910             isInteraction = true;
18911             app.fgInteractionTime = 0;
18912         } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
18913             if (app.fgInteractionTime == 0) {
18914                 app.fgInteractionTime = nowElapsed;
18915                 isInteraction = false;
18916             } else {
18917                 isInteraction = nowElapsed > app.fgInteractionTime + SERVICE_USAGE_INTERACTION_TIME;
18918             }
18919         } else {
18920             isInteraction = app.curProcState
18921                     <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18922             app.fgInteractionTime = 0;
18923         }
18924         if (isInteraction && (!app.reportedInteraction
18925                 || (nowElapsed-app.interactionEventTime) > USAGE_STATS_INTERACTION_INTERVAL)) {
18926             app.interactionEventTime = nowElapsed;
18927             String[] packages = app.getPackageList();
18928             if (packages != null) {
18929                 for (int i = 0; i < packages.length; i++) {
18930                     mUsageStatsService.reportEvent(packages[i], app.userId,
18931                             UsageEvents.Event.SYSTEM_INTERACTION);
18932                 }
18933             }
18934         }
18935         app.reportedInteraction = isInteraction;
18936         if (!isInteraction) {
18937             app.interactionEventTime = 0;
18938         }
18939     }
18940
18941     private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
18942         if (proc.thread != null) {
18943             if (proc.baseProcessTracker != null) {
18944                 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
18945             }
18946             if (proc.repProcState >= 0) {
18947                 mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
18948                         proc.repProcState);
18949             }
18950         }
18951     }
18952
18953     private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
18954             ProcessRecord TOP_APP, boolean doingAll, long now) {
18955         if (app.thread == null) {
18956             return false;
18957         }
18958
18959         computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
18960
18961         return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
18962     }
18963
18964     final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
18965             boolean oomAdj) {
18966         if (isForeground != proc.foregroundServices) {
18967             proc.foregroundServices = isForeground;
18968             ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
18969                     proc.info.uid);
18970             if (isForeground) {
18971                 if (curProcs == null) {
18972                     curProcs = new ArrayList<ProcessRecord>();
18973                     mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
18974                 }
18975                 if (!curProcs.contains(proc)) {
18976                     curProcs.add(proc);
18977                     mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
18978                             proc.info.packageName, proc.info.uid);
18979                 }
18980             } else {
18981                 if (curProcs != null) {
18982                     if (curProcs.remove(proc)) {
18983                         mBatteryStatsService.noteEvent(
18984                                 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
18985                                 proc.info.packageName, proc.info.uid);
18986                         if (curProcs.size() <= 0) {
18987                             mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
18988                         }
18989                     }
18990                 }
18991             }
18992             if (oomAdj) {
18993                 updateOomAdjLocked();
18994             }
18995         }
18996     }
18997
18998     private final ActivityRecord resumedAppLocked() {
18999         ActivityRecord act = mStackSupervisor.resumedAppLocked();
19000         String pkg;
19001         int uid;
19002         if (act != null) {
19003             pkg = act.packageName;
19004             uid = act.info.applicationInfo.uid;
19005         } else {
19006             pkg = null;
19007             uid = -1;
19008         }
19009         // Has the UID or resumed package name changed?
19010         if (uid != mCurResumedUid || (pkg != mCurResumedPackage
19011                 && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
19012             if (mCurResumedPackage != null) {
19013                 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
19014                         mCurResumedPackage, mCurResumedUid);
19015             }
19016             mCurResumedPackage = pkg;
19017             mCurResumedUid = uid;
19018             if (mCurResumedPackage != null) {
19019                 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
19020                         mCurResumedPackage, mCurResumedUid);
19021             }
19022         }
19023         return act;
19024     }
19025
19026     final boolean updateOomAdjLocked(ProcessRecord app) {
19027         final ActivityRecord TOP_ACT = resumedAppLocked();
19028         final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
19029         final boolean wasCached = app.cached;
19030
19031         mAdjSeq++;
19032
19033         // This is the desired cached adjusment we want to tell it to use.
19034         // If our app is currently cached, we know it, and that is it.  Otherwise,
19035         // we don't know it yet, and it needs to now be cached we will then
19036         // need to do a complete oom adj.
19037         final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
19038                 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
19039         boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
19040                 SystemClock.uptimeMillis());
19041         if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
19042             // Changed to/from cached state, so apps after it in the LRU
19043             // list may also be changed.
19044             updateOomAdjLocked();
19045         }
19046         return success;
19047     }
19048
19049     final void updateOomAdjLocked() {
19050         final ActivityRecord TOP_ACT = resumedAppLocked();
19051         final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
19052         final long now = SystemClock.uptimeMillis();
19053         final long nowElapsed = SystemClock.elapsedRealtime();
19054         final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
19055         final int N = mLruProcesses.size();
19056
19057         if (false) {
19058             RuntimeException e = new RuntimeException();
19059             e.fillInStackTrace();
19060             Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
19061         }
19062
19063         // Reset state in all uid records.
19064         for (int i=mActiveUids.size()-1; i>=0; i--) {
19065             final UidRecord uidRec = mActiveUids.valueAt(i);
19066             if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19067                     "Starting update of " + uidRec);
19068             uidRec.reset();
19069         }
19070
19071         mAdjSeq++;
19072         mNewNumServiceProcs = 0;
19073         mNewNumAServiceProcs = 0;
19074
19075         final int emptyProcessLimit;
19076         final int cachedProcessLimit;
19077         if (mProcessLimit <= 0) {
19078             emptyProcessLimit = cachedProcessLimit = 0;
19079         } else if (mProcessLimit == 1) {
19080             emptyProcessLimit = 1;
19081             cachedProcessLimit = 0;
19082         } else {
19083             emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
19084             cachedProcessLimit = mProcessLimit - emptyProcessLimit;
19085         }
19086
19087         // Let's determine how many processes we have running vs.
19088         // how many slots we have for background processes; we may want
19089         // to put multiple processes in a slot of there are enough of
19090         // them.
19091         int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
19092                 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
19093         int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
19094         if (numEmptyProcs > cachedProcessLimit) {
19095             // If there are more empty processes than our limit on cached
19096             // processes, then use the cached process limit for the factor.
19097             // This ensures that the really old empty processes get pushed
19098             // down to the bottom, so if we are running low on memory we will
19099             // have a better chance at keeping around more cached processes
19100             // instead of a gazillion empty processes.
19101             numEmptyProcs = cachedProcessLimit;
19102         }
19103         int emptyFactor = numEmptyProcs/numSlots;
19104         if (emptyFactor < 1) emptyFactor = 1;
19105         int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
19106         if (cachedFactor < 1) cachedFactor = 1;
19107         int stepCached = 0;
19108         int stepEmpty = 0;
19109         int numCached = 0;
19110         int numEmpty = 0;
19111         int numTrimming = 0;
19112
19113         mNumNonCachedProcs = 0;
19114         mNumCachedHiddenProcs = 0;
19115
19116         // First update the OOM adjustment for each of the
19117         // application processes based on their current state.
19118         int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
19119         int nextCachedAdj = curCachedAdj+1;
19120         int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
19121         int nextEmptyAdj = curEmptyAdj+2;
19122         for (int i=N-1; i>=0; i--) {
19123             ProcessRecord app = mLruProcesses.get(i);
19124             if (!app.killedByAm && app.thread != null) {
19125                 app.procStateChanged = false;
19126                 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
19127
19128                 // If we haven't yet assigned the final cached adj
19129                 // to the process, do that now.
19130                 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
19131                     switch (app.curProcState) {
19132                         case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
19133                         case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
19134                             // This process is a cached process holding activities...
19135                             // assign it the next cached value for that type, and then
19136                             // step that cached level.
19137                             app.curRawAdj = curCachedAdj;
19138                             app.curAdj = app.modifyRawOomAdj(curCachedAdj);
19139                             if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
19140                                     + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
19141                                     + ")");
19142                             if (curCachedAdj != nextCachedAdj) {
19143                                 stepCached++;
19144                                 if (stepCached >= cachedFactor) {
19145                                     stepCached = 0;
19146                                     curCachedAdj = nextCachedAdj;
19147                                     nextCachedAdj += 2;
19148                                     if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
19149                                         nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
19150                                     }
19151                                 }
19152                             }
19153                             break;
19154                         default:
19155                             // For everything else, assign next empty cached process
19156                             // level and bump that up.  Note that this means that
19157                             // long-running services that have dropped down to the
19158                             // cached level will be treated as empty (since their process
19159                             // state is still as a service), which is what we want.
19160                             app.curRawAdj = curEmptyAdj;
19161                             app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
19162                             if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
19163                                     + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
19164                                     + ")");
19165                             if (curEmptyAdj != nextEmptyAdj) {
19166                                 stepEmpty++;
19167                                 if (stepEmpty >= emptyFactor) {
19168                                     stepEmpty = 0;
19169                                     curEmptyAdj = nextEmptyAdj;
19170                                     nextEmptyAdj += 2;
19171                                     if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
19172                                         nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
19173                                     }
19174                                 }
19175                             }
19176                             break;
19177                     }
19178                 }
19179
19180                 applyOomAdjLocked(app, true, now, nowElapsed);
19181
19182                 // Count the number of process types.
19183                 switch (app.curProcState) {
19184                     case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
19185                     case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
19186                         mNumCachedHiddenProcs++;
19187                         numCached++;
19188                         if (numCached > cachedProcessLimit) {
19189                             app.kill("cached #" + numCached, true);
19190                         }
19191                         break;
19192                     case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
19193                         if (numEmpty > ProcessList.TRIM_EMPTY_APPS
19194                                 && app.lastActivityTime < oldTime) {
19195                             app.kill("empty for "
19196                                     + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
19197                                     / 1000) + "s", true);
19198                         } else {
19199                             numEmpty++;
19200                             if (numEmpty > emptyProcessLimit) {
19201                                 app.kill("empty #" + numEmpty, true);
19202                             }
19203                         }
19204                         break;
19205                     default:
19206                         mNumNonCachedProcs++;
19207                         break;
19208                 }
19209
19210                 if (app.isolated && app.services.size() <= 0) {
19211                     // If this is an isolated process, and there are no
19212                     // services running in it, then the process is no longer
19213                     // needed.  We agressively kill these because we can by
19214                     // definition not re-use the same process again, and it is
19215                     // good to avoid having whatever code was running in them
19216                     // left sitting around after no longer needed.
19217                     app.kill("isolated not needed", true);
19218                 } else {
19219                     // Keeping this process, update its uid.
19220                     final UidRecord uidRec = app.uidRecord;
19221                     if (uidRec != null && uidRec.curProcState > app.curProcState) {
19222                         uidRec.curProcState = app.curProcState;
19223                     }
19224                 }
19225
19226                 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
19227                         && !app.killedByAm) {
19228                     numTrimming++;
19229                 }
19230             }
19231         }
19232
19233         mNumServiceProcs = mNewNumServiceProcs;
19234
19235         // Now determine the memory trimming level of background processes.
19236         // Unfortunately we need to start at the back of the list to do this
19237         // properly.  We only do this if the number of background apps we
19238         // are managing to keep around is less than half the maximum we desire;
19239         // if we are keeping a good number around, we'll let them use whatever
19240         // memory they want.
19241         final int numCachedAndEmpty = numCached + numEmpty;
19242         int memFactor;
19243         if (numCached <= ProcessList.TRIM_CACHED_APPS
19244                 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
19245             if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
19246                 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
19247             } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
19248                 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
19249             } else {
19250                 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
19251             }
19252         } else {
19253             memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
19254         }
19255         // We always allow the memory level to go up (better).  We only allow it to go
19256         // down if we are in a state where that is allowed, *and* the total number of processes
19257         // has gone down since last time.
19258         if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
19259                 + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
19260                 + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
19261         if (memFactor > mLastMemoryLevel) {
19262             if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
19263                 memFactor = mLastMemoryLevel;
19264                 if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
19265             }
19266         }
19267         mLastMemoryLevel = memFactor;
19268         mLastNumProcesses = mLruProcesses.size();
19269         boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
19270         final int trackerMemFactor = mProcessStats.getMemFactorLocked();
19271         if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
19272             if (mLowRamStartTime == 0) {
19273                 mLowRamStartTime = now;
19274             }
19275             int step = 0;
19276             int fgTrimLevel;
19277             switch (memFactor) {
19278                 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
19279                     fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
19280                     break;
19281                 case ProcessStats.ADJ_MEM_FACTOR_LOW:
19282                     fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
19283                     break;
19284                 default:
19285                     fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
19286                     break;
19287             }
19288             int factor = numTrimming/3;
19289             int minFactor = 2;
19290             if (mHomeProcess != null) minFactor++;
19291             if (mPreviousProcess != null) minFactor++;
19292             if (factor < minFactor) factor = minFactor;
19293             int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
19294             for (int i=N-1; i>=0; i--) {
19295                 ProcessRecord app = mLruProcesses.get(i);
19296                 if (allChanged || app.procStateChanged) {
19297                     setProcessTrackerStateLocked(app, trackerMemFactor, now);
19298                     app.procStateChanged = false;
19299                 }
19300                 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
19301                         && !app.killedByAm) {
19302                     if (app.trimMemoryLevel < curLevel && app.thread != null) {
19303                         try {
19304                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19305                                     "Trimming memory of " + app.processName + " to " + curLevel);
19306                             app.thread.scheduleTrimMemory(curLevel);
19307                         } catch (RemoteException e) {
19308                         }
19309                         if (false) {
19310                             // For now we won't do this; our memory trimming seems
19311                             // to be good enough at this point that destroying
19312                             // activities causes more harm than good.
19313                             if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
19314                                     && app != mHomeProcess && app != mPreviousProcess) {
19315                                 // Need to do this on its own message because the stack may not
19316                                 // be in a consistent state at this point.
19317                                 // For these apps we will also finish their activities
19318                                 // to help them free memory.
19319                                 mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
19320                             }
19321                         }
19322                     }
19323                     app.trimMemoryLevel = curLevel;
19324                     step++;
19325                     if (step >= factor) {
19326                         step = 0;
19327                         switch (curLevel) {
19328                             case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
19329                                 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
19330                                 break;
19331                             case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
19332                                 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
19333                                 break;
19334                         }
19335                     }
19336                 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
19337                     if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
19338                             && app.thread != null) {
19339                         try {
19340                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19341                                     "Trimming memory of heavy-weight " + app.processName
19342                                     + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
19343                             app.thread.scheduleTrimMemory(
19344                                     ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
19345                         } catch (RemoteException e) {
19346                         }
19347                     }
19348                     app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
19349                 } else {
19350                     if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
19351                             || app.systemNoUi) && app.pendingUiClean) {
19352                         // If this application is now in the background and it
19353                         // had done UI, then give it the special trim level to
19354                         // have it free UI resources.
19355                         final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
19356                         if (app.trimMemoryLevel < level && app.thread != null) {
19357                             try {
19358                                 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19359                                         "Trimming memory of bg-ui " + app.processName
19360                                         + " to " + level);
19361                                 app.thread.scheduleTrimMemory(level);
19362                             } catch (RemoteException e) {
19363                             }
19364                         }
19365                         app.pendingUiClean = false;
19366                     }
19367                     if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
19368                         try {
19369                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19370                                     "Trimming memory of fg " + app.processName
19371                                     + " to " + fgTrimLevel);
19372                             app.thread.scheduleTrimMemory(fgTrimLevel);
19373                         } catch (RemoteException e) {
19374                         }
19375                     }
19376                     app.trimMemoryLevel = fgTrimLevel;
19377                 }
19378             }
19379         } else {
19380             if (mLowRamStartTime != 0) {
19381                 mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
19382                 mLowRamStartTime = 0;
19383             }
19384             for (int i=N-1; i>=0; i--) {
19385                 ProcessRecord app = mLruProcesses.get(i);
19386                 if (allChanged || app.procStateChanged) {
19387                     setProcessTrackerStateLocked(app, trackerMemFactor, now);
19388                     app.procStateChanged = false;
19389                 }
19390                 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
19391                         || app.systemNoUi) && app.pendingUiClean) {
19392                     if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
19393                             && app.thread != null) {
19394                         try {
19395                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19396                                     "Trimming memory of ui hidden " + app.processName
19397                                     + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
19398                             app.thread.scheduleTrimMemory(
19399                                     ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
19400                         } catch (RemoteException e) {
19401                         }
19402                     }
19403                     app.pendingUiClean = false;
19404                 }
19405                 app.trimMemoryLevel = 0;
19406             }
19407         }
19408
19409         if (mAlwaysFinishActivities) {
19410             // Need to do this on its own message because the stack may not
19411             // be in a consistent state at this point.
19412             mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
19413         }
19414
19415         if (allChanged) {
19416             requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
19417         }
19418
19419         // Update from any uid changes.
19420         for (int i=mActiveUids.size()-1; i>=0; i--) {
19421             final UidRecord uidRec = mActiveUids.valueAt(i);
19422             if (uidRec.setProcState != uidRec.curProcState) {
19423                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19424                         "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
19425                         + " to " + uidRec.curProcState);
19426                 uidRec.setProcState = uidRec.curProcState;
19427                 enqueueUidChangeLocked(uidRec, false);
19428             }
19429         }
19430
19431         if (mProcessStats.shouldWriteNowLocked(now)) {
19432             mHandler.post(new Runnable() {
19433                 @Override public void run() {
19434                     synchronized (ActivityManagerService.this) {
19435                         mProcessStats.writeStateAsyncLocked();
19436                     }
19437                 }
19438             });
19439         }
19440
19441         if (DEBUG_OOM_ADJ) {
19442             final long duration = SystemClock.uptimeMillis() - now;
19443             if (false) {
19444                 Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
19445                         new RuntimeException("here").fillInStackTrace());
19446             } else {
19447                 Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
19448             }
19449         }
19450     }
19451
19452     final void trimApplications() {
19453         synchronized (this) {
19454             int i;
19455
19456             // First remove any unused application processes whose package
19457             // has been removed.
19458             for (i=mRemovedProcesses.size()-1; i>=0; i--) {
19459                 final ProcessRecord app = mRemovedProcesses.get(i);
19460                 if (app.activities.size() == 0
19461                         && app.curReceiver == null && app.services.size() == 0) {
19462                     Slog.i(
19463                         TAG, "Exiting empty application process "
19464                         + app.processName + " ("
19465                         + (app.thread != null ? app.thread.asBinder() : null)
19466                         + ")\n");
19467                     if (app.pid > 0 && app.pid != MY_PID) {
19468                         app.kill("empty", false);
19469                     } else {
19470                         try {
19471                             app.thread.scheduleExit();
19472                         } catch (Exception e) {
19473                             // Ignore exceptions.
19474                         }
19475                     }
19476                     cleanUpApplicationRecordLocked(app, false, true, -1);
19477                     mRemovedProcesses.remove(i);
19478
19479                     if (app.persistent) {
19480                         addAppLocked(app.info, false, null /* ABI override */);
19481                     }
19482                 }
19483             }
19484
19485             // Now update the oom adj for all processes.
19486             updateOomAdjLocked();
19487         }
19488     }
19489
19490     /** This method sends the specified signal to each of the persistent apps */
19491     public void signalPersistentProcesses(int sig) throws RemoteException {
19492         if (sig != Process.SIGNAL_USR1) {
19493             throw new SecurityException("Only SIGNAL_USR1 is allowed");
19494         }
19495
19496         synchronized (this) {
19497             if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
19498                     != PackageManager.PERMISSION_GRANTED) {
19499                 throw new SecurityException("Requires permission "
19500                         + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
19501             }
19502
19503             for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
19504                 ProcessRecord r = mLruProcesses.get(i);
19505                 if (r.thread != null && r.persistent) {
19506                     Process.sendSignal(r.pid, sig);
19507                 }
19508             }
19509         }
19510     }
19511
19512     private void stopProfilerLocked(ProcessRecord proc, int profileType) {
19513         if (proc == null || proc == mProfileProc) {
19514             proc = mProfileProc;
19515             profileType = mProfileType;
19516             clearProfilerLocked();
19517         }
19518         if (proc == null) {
19519             return;
19520         }
19521         try {
19522             proc.thread.profilerControl(false, null, profileType);
19523         } catch (RemoteException e) {
19524             throw new IllegalStateException("Process disappeared");
19525         }
19526     }
19527
19528     private void clearProfilerLocked() {
19529         if (mProfileFd != null) {
19530             try {
19531                 mProfileFd.close();
19532             } catch (IOException e) {
19533             }
19534         }
19535         mProfileApp = null;
19536         mProfileProc = null;
19537         mProfileFile = null;
19538         mProfileType = 0;
19539         mAutoStopProfiler = false;
19540         mSamplingInterval = 0;
19541     }
19542
19543     public boolean profileControl(String process, int userId, boolean start,
19544             ProfilerInfo profilerInfo, int profileType) throws RemoteException {
19545
19546         try {
19547             synchronized (this) {
19548                 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
19549                 // its own permission.
19550                 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
19551                         != PackageManager.PERMISSION_GRANTED) {
19552                     throw new SecurityException("Requires permission "
19553                             + android.Manifest.permission.SET_ACTIVITY_WATCHER);
19554                 }
19555
19556                 if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
19557                     throw new IllegalArgumentException("null profile info or fd");
19558                 }
19559
19560                 ProcessRecord proc = null;
19561                 if (process != null) {
19562                     proc = findProcessLocked(process, userId, "profileControl");
19563                 }
19564
19565                 if (start && (proc == null || proc.thread == null)) {
19566                     throw new IllegalArgumentException("Unknown process: " + process);
19567                 }
19568
19569                 if (start) {
19570                     stopProfilerLocked(null, 0);
19571                     setProfileApp(proc.info, proc.processName, profilerInfo);
19572                     mProfileProc = proc;
19573                     mProfileType = profileType;
19574                     ParcelFileDescriptor fd = profilerInfo.profileFd;
19575                     try {
19576                         fd = fd.dup();
19577                     } catch (IOException e) {
19578                         fd = null;
19579                     }
19580                     profilerInfo.profileFd = fd;
19581                     proc.thread.profilerControl(start, profilerInfo, profileType);
19582                     fd = null;
19583                     mProfileFd = null;
19584                 } else {
19585                     stopProfilerLocked(proc, profileType);
19586                     if (profilerInfo != null && profilerInfo.profileFd != null) {
19587                         try {
19588                             profilerInfo.profileFd.close();
19589                         } catch (IOException e) {
19590                         }
19591                     }
19592                 }
19593
19594                 return true;
19595             }
19596         } catch (RemoteException e) {
19597             throw new IllegalStateException("Process disappeared");
19598         } finally {
19599             if (profilerInfo != null && profilerInfo.profileFd != null) {
19600                 try {
19601                     profilerInfo.profileFd.close();
19602                 } catch (IOException e) {
19603                 }
19604             }
19605         }
19606     }
19607
19608     private ProcessRecord findProcessLocked(String process, int userId, String callName) {
19609         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
19610                 userId, true, ALLOW_FULL_ONLY, callName, null);
19611         ProcessRecord proc = null;
19612         try {
19613             int pid = Integer.parseInt(process);
19614             synchronized (mPidsSelfLocked) {
19615                 proc = mPidsSelfLocked.get(pid);
19616             }
19617         } catch (NumberFormatException e) {
19618         }
19619
19620         if (proc == null) {
19621             ArrayMap<String, SparseArray<ProcessRecord>> all
19622                     = mProcessNames.getMap();
19623             SparseArray<ProcessRecord> procs = all.get(process);
19624             if (procs != null && procs.size() > 0) {
19625                 proc = procs.valueAt(0);
19626                 if (userId != UserHandle.USER_ALL && proc.userId != userId) {
19627                     for (int i=1; i<procs.size(); i++) {
19628                         ProcessRecord thisProc = procs.valueAt(i);
19629                         if (thisProc.userId == userId) {
19630                             proc = thisProc;
19631                             break;
19632                         }
19633                     }
19634                 }
19635             }
19636         }
19637
19638         return proc;
19639     }
19640
19641     public boolean dumpHeap(String process, int userId, boolean managed,
19642             String path, ParcelFileDescriptor fd) throws RemoteException {
19643
19644         try {
19645             synchronized (this) {
19646                 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
19647                 // its own permission (same as profileControl).
19648                 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
19649                         != PackageManager.PERMISSION_GRANTED) {
19650                     throw new SecurityException("Requires permission "
19651                             + android.Manifest.permission.SET_ACTIVITY_WATCHER);
19652                 }
19653
19654                 if (fd == null) {
19655                     throw new IllegalArgumentException("null fd");
19656                 }
19657
19658                 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
19659                 if (proc == null || proc.thread == null) {
19660                     throw new IllegalArgumentException("Unknown process: " + process);
19661                 }
19662
19663                 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
19664                 if (!isDebuggable) {
19665                     if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
19666                         throw new SecurityException("Process not debuggable: " + proc);
19667                     }
19668                 }
19669
19670                 proc.thread.dumpHeap(managed, path, fd);
19671                 fd = null;
19672                 return true;
19673             }
19674         } catch (RemoteException e) {
19675             throw new IllegalStateException("Process disappeared");
19676         } finally {
19677             if (fd != null) {
19678                 try {
19679                     fd.close();
19680                 } catch (IOException e) {
19681                 }
19682             }
19683         }
19684     }
19685
19686     @Override
19687     public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
19688             String reportPackage) {
19689         if (processName != null) {
19690             enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
19691                     "setDumpHeapDebugLimit()");
19692         } else {
19693             synchronized (mPidsSelfLocked) {
19694                 ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
19695                 if (proc == null) {
19696                     throw new SecurityException("No process found for calling pid "
19697                             + Binder.getCallingPid());
19698                 }
19699                 if (!Build.IS_DEBUGGABLE
19700                         && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
19701                     throw new SecurityException("Not running a debuggable build");
19702                 }
19703                 processName = proc.processName;
19704                 uid = proc.uid;
19705                 if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
19706                     throw new SecurityException("Package " + reportPackage + " is not running in "
19707                             + proc);
19708                 }
19709             }
19710         }
19711         synchronized (this) {
19712             if (maxMemSize > 0) {
19713                 mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
19714             } else {
19715                 if (uid != 0) {
19716                     mMemWatchProcesses.remove(processName, uid);
19717                 } else {
19718                     mMemWatchProcesses.getMap().remove(processName);
19719                 }
19720             }
19721         }
19722     }
19723
19724     @Override
19725     public void dumpHeapFinished(String path) {
19726         synchronized (this) {
19727             if (Binder.getCallingPid() != mMemWatchDumpPid) {
19728                 Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
19729                         + " does not match last pid " + mMemWatchDumpPid);
19730                 return;
19731             }
19732             if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
19733                 Slog.w(TAG, "dumpHeapFinished: Calling path " + path
19734                         + " does not match last path " + mMemWatchDumpFile);
19735                 return;
19736             }
19737             if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
19738             mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
19739         }
19740     }
19741
19742     /** In this method we try to acquire our lock to make sure that we have not deadlocked */
19743     public void monitor() {
19744         synchronized (this) { }
19745     }
19746
19747     void onCoreSettingsChange(Bundle settings) {
19748         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
19749             ProcessRecord processRecord = mLruProcesses.get(i);
19750             try {
19751                 if (processRecord.thread != null) {
19752                     processRecord.thread.setCoreSettings(settings);
19753                 }
19754             } catch (RemoteException re) {
19755                 /* ignore */
19756             }
19757         }
19758     }
19759
19760     // Multi-user methods
19761
19762     /**
19763      * Start user, if its not already running, but don't bring it to foreground.
19764      */
19765     @Override
19766     public boolean startUserInBackground(final int userId) {
19767         return startUser(userId, /* foreground */ false);
19768     }
19769
19770     /**
19771      * Start user, if its not already running, and bring it to foreground.
19772      */
19773     boolean startUserInForeground(final int userId, Dialog dlg) {
19774         boolean result = startUser(userId, /* foreground */ true);
19775         dlg.dismiss();
19776         return result;
19777     }
19778
19779     /**
19780      * Refreshes the list of users related to the current user when either a
19781      * user switch happens or when a new related user is started in the
19782      * background.
19783      */
19784     private void updateCurrentProfileIdsLocked() {
19785         final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
19786                 mCurrentUserId, false /* enabledOnly */);
19787         int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
19788         for (int i = 0; i < currentProfileIds.length; i++) {
19789             currentProfileIds[i] = profiles.get(i).id;
19790         }
19791         mCurrentProfileIds = currentProfileIds;
19792
19793         synchronized (mUserProfileGroupIdsSelfLocked) {
19794             mUserProfileGroupIdsSelfLocked.clear();
19795             final List<UserInfo> users = getUserManagerLocked().getUsers(false);
19796             for (int i = 0; i < users.size(); i++) {
19797                 UserInfo user = users.get(i);
19798                 if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
19799                     mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
19800                 }
19801             }
19802         }
19803     }
19804
19805     private Set<Integer> getProfileIdsLocked(int userId) {
19806         Set<Integer> userIds = new HashSet<Integer>();
19807         final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
19808                 userId, false /* enabledOnly */);
19809         for (UserInfo user : profiles) {
19810             userIds.add(Integer.valueOf(user.id));
19811         }
19812         return userIds;
19813     }
19814
19815     @Override
19816     public boolean switchUser(final int userId) {
19817         enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
19818         String userName;
19819         synchronized (this) {
19820             UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
19821             if (userInfo == null) {
19822                 Slog.w(TAG, "No user info for user #" + userId);
19823                 return false;
19824             }
19825             if (userInfo.isManagedProfile()) {
19826                 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
19827                 return false;
19828             }
19829             userName = userInfo.name;
19830             mTargetUserId = userId;
19831         }
19832         mUiHandler.removeMessages(START_USER_SWITCH_MSG);
19833         mUiHandler.sendMessage(mUiHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName));
19834         return true;
19835     }
19836
19837     private void showUserSwitchDialog(int userId, String userName) {
19838         // The dialog will show and then initiate the user switch by calling startUserInForeground
19839         Dialog d = new UserSwitchingDialog(this, mContext, userId, userName,
19840                 true /* above system */);
19841         d.show();
19842     }
19843
19844     private boolean startUser(final int userId, final boolean foreground) {
19845         if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
19846                 != PackageManager.PERMISSION_GRANTED) {
19847             String msg = "Permission Denial: switchUser() from pid="
19848                     + Binder.getCallingPid()
19849                     + ", uid=" + Binder.getCallingUid()
19850                     + " requires " + INTERACT_ACROSS_USERS_FULL;
19851             Slog.w(TAG, msg);
19852             throw new SecurityException(msg);
19853         }
19854
19855         if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
19856
19857         final long ident = Binder.clearCallingIdentity();
19858         try {
19859             synchronized (this) {
19860                 final int oldUserId = mCurrentUserId;
19861                 if (oldUserId == userId) {
19862                     return true;
19863                 }
19864
19865                 mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
19866                         "startUser", false);
19867
19868                 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
19869                 if (userInfo == null) {
19870                     Slog.w(TAG, "No user info for user #" + userId);
19871                     return false;
19872                 }
19873                 if (foreground && userInfo.isManagedProfile()) {
19874                     Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
19875                     return false;
19876                 }
19877
19878                 if (foreground) {
19879                     mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
19880                             R.anim.screen_user_enter);
19881                 }
19882
19883                 boolean needStart = false;
19884
19885                 // If the user we are switching to is not currently started, then
19886                 // we need to start it now.
19887                 if (mStartedUsers.get(userId) == null) {
19888                     mStartedUsers.put(userId, new UserState(new UserHandle(userId), false));
19889                     updateStartedUserArrayLocked();
19890                     needStart = true;
19891                 }
19892
19893                 final Integer userIdInt = Integer.valueOf(userId);
19894                 mUserLru.remove(userIdInt);
19895                 mUserLru.add(userIdInt);
19896
19897                 if (foreground) {
19898                     mCurrentUserId = userId;
19899                     mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up
19900                     updateCurrentProfileIdsLocked();
19901                     mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
19902                     // Once the internal notion of the active user has switched, we lock the device
19903                     // with the option to show the user switcher on the keyguard.
19904                     mWindowManager.lockNow(null);
19905                 } else {
19906                     final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
19907                     updateCurrentProfileIdsLocked();
19908                     mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
19909                     mUserLru.remove(currentUserIdInt);
19910                     mUserLru.add(currentUserIdInt);
19911                 }
19912
19913                 final UserState uss = mStartedUsers.get(userId);
19914
19915                 // Make sure user is in the started state.  If it is currently
19916                 // stopping, we need to knock that off.
19917                 if (uss.mState == UserState.STATE_STOPPING) {
19918                     // If we are stopping, we haven't sent ACTION_SHUTDOWN,
19919                     // so we can just fairly silently bring the user back from
19920                     // the almost-dead.
19921                     uss.mState = UserState.STATE_RUNNING;
19922                     updateStartedUserArrayLocked();
19923                     needStart = true;
19924                 } else if (uss.mState == UserState.STATE_SHUTDOWN) {
19925                     // This means ACTION_SHUTDOWN has been sent, so we will
19926                     // need to treat this as a new boot of the user.
19927                     uss.mState = UserState.STATE_BOOTING;
19928                     updateStartedUserArrayLocked();
19929                     needStart = true;
19930                 }
19931
19932                 if (uss.mState == UserState.STATE_BOOTING) {
19933                     // Booting up a new user, need to tell system services about it.
19934                     // Note that this is on the same handler as scheduling of broadcasts,
19935                     // which is important because it needs to go first.
19936                     mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
19937                 }
19938
19939                 if (foreground) {
19940                     mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
19941                             oldUserId));
19942                     mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
19943                     mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
19944                     mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
19945                             oldUserId, userId, uss));
19946                     mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
19947                             oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
19948                 }
19949
19950                 if (needStart) {
19951                     // Send USER_STARTED broadcast
19952                     Intent intent = new Intent(Intent.ACTION_USER_STARTED);
19953                     intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
19954                             | Intent.FLAG_RECEIVER_FOREGROUND);
19955                     intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
19956                     broadcastIntentLocked(null, null, intent,
19957                             null, null, 0, null, null, null, AppOpsManager.OP_NONE,
19958                             null, false, false, MY_PID, Process.SYSTEM_UID, userId);
19959                 }
19960
19961                 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
19962                     if (userId != UserHandle.USER_OWNER) {
19963                         Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
19964                         intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
19965                         broadcastIntentLocked(null, null, intent, null,
19966                                 new IIntentReceiver.Stub() {
19967                                     public void performReceive(Intent intent, int resultCode,
19968                                             String data, Bundle extras, boolean ordered,
19969                                             boolean sticky, int sendingUser) {
19970                                         onUserInitialized(uss, foreground, oldUserId, userId);
19971                                     }
19972                                 }, 0, null, null, null, AppOpsManager.OP_NONE,
19973                                 null, true, false, MY_PID, Process.SYSTEM_UID, userId);
19974                         uss.initializing = true;
19975                     } else {
19976                         getUserManagerLocked().makeInitialized(userInfo.id);
19977                     }
19978                 }
19979
19980                 if (foreground) {
19981                     if (!uss.initializing) {
19982                         moveUserToForeground(uss, oldUserId, userId);
19983                     }
19984                 } else {
19985                     mStackSupervisor.startBackgroundUserLocked(userId, uss);
19986                 }
19987
19988                 if (needStart) {
19989                     Intent intent = new Intent(Intent.ACTION_USER_STARTING);
19990                     intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19991                     intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
19992                     broadcastIntentLocked(null, null, intent,
19993                             null, new IIntentReceiver.Stub() {
19994                                 @Override
19995                                 public void performReceive(Intent intent, int resultCode,
19996                                         String data, Bundle extras, boolean ordered, boolean sticky,
19997                                         int sendingUser) throws RemoteException {
19998                                 }
19999                             }, 0, null, null,
20000                             new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
20001                             null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
20002                 }
20003             }
20004         } finally {
20005             Binder.restoreCallingIdentity(ident);
20006         }
20007
20008         return true;
20009     }
20010
20011     void dispatchForegroundProfileChanged(int userId) {
20012         final int N = mUserSwitchObservers.beginBroadcast();
20013         for (int i = 0; i < N; i++) {
20014             try {
20015                 mUserSwitchObservers.getBroadcastItem(i).onForegroundProfileSwitch(userId);
20016             } catch (RemoteException e) {
20017                 // Ignore
20018             }
20019         }
20020         mUserSwitchObservers.finishBroadcast();
20021     }
20022
20023     void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
20024         long ident = Binder.clearCallingIdentity();
20025         try {
20026             Intent intent;
20027             if (oldUserId >= 0) {
20028                 // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
20029                 List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
20030                 int count = profiles.size();
20031                 for (int i = 0; i < count; i++) {
20032                     int profileUserId = profiles.get(i).id;
20033                     intent = new Intent(Intent.ACTION_USER_BACKGROUND);
20034                     intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
20035                             | Intent.FLAG_RECEIVER_FOREGROUND);
20036                     intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
20037                     broadcastIntentLocked(null, null, intent,
20038                             null, null, 0, null, null, null, AppOpsManager.OP_NONE,
20039                             null, false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
20040                 }
20041             }
20042             if (newUserId >= 0) {
20043                 // Send USER_FOREGROUND broadcast to all profiles of the incoming user
20044                 List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
20045                 int count = profiles.size();
20046                 for (int i = 0; i < count; i++) {
20047                     int profileUserId = profiles.get(i).id;
20048                     intent = new Intent(Intent.ACTION_USER_FOREGROUND);
20049                     intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
20050                             | Intent.FLAG_RECEIVER_FOREGROUND);
20051                     intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
20052                     broadcastIntentLocked(null, null, intent,
20053                             null, null, 0, null, null, null, AppOpsManager.OP_NONE,
20054                             null, false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
20055                 }
20056                 intent = new Intent(Intent.ACTION_USER_SWITCHED);
20057                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
20058                         | Intent.FLAG_RECEIVER_FOREGROUND);
20059                 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
20060                 broadcastIntentLocked(null, null, intent,
20061                         null, null, 0, null, null,
20062                         new String[] {android.Manifest.permission.MANAGE_USERS},
20063                         AppOpsManager.OP_NONE, null, false, false, MY_PID, Process.SYSTEM_UID,
20064                         UserHandle.USER_ALL);
20065             }
20066         } finally {
20067             Binder.restoreCallingIdentity(ident);
20068         }
20069     }
20070
20071     void dispatchUserSwitch(final UserState uss, final int oldUserId,
20072             final int newUserId) {
20073         final int N = mUserSwitchObservers.beginBroadcast();
20074         if (N > 0) {
20075             final IRemoteCallback callback = new IRemoteCallback.Stub() {
20076                 int mCount = 0;
20077                 @Override
20078                 public void sendResult(Bundle data) throws RemoteException {
20079                     synchronized (ActivityManagerService.this) {
20080                         if (mCurUserSwitchCallback == this) {
20081                             mCount++;
20082                             if (mCount == N) {
20083                                 sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
20084                             }
20085                         }
20086                     }
20087                 }
20088             };
20089             synchronized (this) {
20090                 uss.switching = true;
20091                 mCurUserSwitchCallback = callback;
20092             }
20093             for (int i=0; i<N; i++) {
20094                 try {
20095                     mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
20096                             newUserId, callback);
20097                 } catch (RemoteException e) {
20098                 }
20099             }
20100         } else {
20101             synchronized (this) {
20102                 sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
20103             }
20104         }
20105         mUserSwitchObservers.finishBroadcast();
20106     }
20107
20108     void timeoutUserSwitch(UserState uss, int oldUserId, int newUserId) {
20109         synchronized (this) {
20110             Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
20111             sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
20112         }
20113     }
20114
20115     void sendContinueUserSwitchLocked(UserState uss, int oldUserId, int newUserId) {
20116         mCurUserSwitchCallback = null;
20117         mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
20118         mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
20119                 oldUserId, newUserId, uss));
20120     }
20121
20122     void onUserInitialized(UserState uss, boolean foreground, int oldUserId, int newUserId) {
20123         synchronized (this) {
20124             if (foreground) {
20125                 moveUserToForeground(uss, oldUserId, newUserId);
20126             }
20127         }
20128
20129         completeSwitchAndInitialize(uss, newUserId, true, false);
20130     }
20131
20132     void moveUserToForeground(UserState uss, int oldUserId, int newUserId) {
20133         boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss);
20134         if (homeInFront) {
20135             startHomeActivityLocked(newUserId, "moveUserToFroreground");
20136         } else {
20137             mStackSupervisor.resumeTopActivitiesLocked();
20138         }
20139         EventLogTags.writeAmSwitchUser(newUserId);
20140         getUserManagerLocked().onUserForeground(newUserId);
20141         sendUserSwitchBroadcastsLocked(oldUserId, newUserId);
20142     }
20143
20144     void continueUserSwitch(UserState uss, int oldUserId, int newUserId) {
20145         completeSwitchAndInitialize(uss, newUserId, false, true);
20146     }
20147
20148     void completeSwitchAndInitialize(UserState uss, int newUserId,
20149             boolean clearInitializing, boolean clearSwitching) {
20150         boolean unfrozen = false;
20151         synchronized (this) {
20152             if (clearInitializing) {
20153                 uss.initializing = false;
20154                 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
20155             }
20156             if (clearSwitching) {
20157                 uss.switching = false;
20158             }
20159             if (!uss.switching && !uss.initializing) {
20160                 mWindowManager.stopFreezingScreen();
20161                 unfrozen = true;
20162             }
20163         }
20164         if (unfrozen) {
20165             mHandler.removeMessages(REPORT_USER_SWITCH_COMPLETE_MSG);
20166             mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_COMPLETE_MSG,
20167                     newUserId, 0));
20168         }
20169         stopGuestUserIfBackground();
20170     }
20171
20172     /** Called on handler thread */
20173     void dispatchUserSwitchComplete(int userId) {
20174         final int observerCount = mUserSwitchObservers.beginBroadcast();
20175         for (int i = 0; i < observerCount; i++) {
20176             try {
20177                 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(userId);
20178             } catch (RemoteException e) {
20179             }
20180         }
20181         mUserSwitchObservers.finishBroadcast();
20182     }
20183
20184     /**
20185      * Stops the guest user if it has gone to the background.
20186      */
20187     private void stopGuestUserIfBackground() {
20188         synchronized (this) {
20189             final int num = mUserLru.size();
20190             for (int i = 0; i < num; i++) {
20191                 Integer oldUserId = mUserLru.get(i);
20192                 UserState oldUss = mStartedUsers.get(oldUserId);
20193                 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId
20194                         || oldUss.mState == UserState.STATE_STOPPING
20195                         || oldUss.mState == UserState.STATE_SHUTDOWN) {
20196                     continue;
20197                 }
20198                 UserInfo userInfo = mUserManager.getUserInfo(oldUserId);
20199                 if (userInfo.isGuest()) {
20200                     // This is a user to be stopped.
20201                     stopUserLocked(oldUserId, null);
20202                     break;
20203                 }
20204             }
20205         }
20206     }
20207
20208     void scheduleStartProfilesLocked() {
20209         if (!mHandler.hasMessages(START_PROFILES_MSG)) {
20210             mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
20211                     DateUtils.SECOND_IN_MILLIS);
20212         }
20213     }
20214
20215     void startProfilesLocked() {
20216         if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
20217         List<UserInfo> profiles = getUserManagerLocked().getProfiles(
20218                 mCurrentUserId, false /* enabledOnly */);
20219         List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
20220         for (UserInfo user : profiles) {
20221             if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
20222                     && user.id != mCurrentUserId) {
20223                 toStart.add(user);
20224             }
20225         }
20226         final int n = toStart.size();
20227         int i = 0;
20228         for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
20229             startUserInBackground(toStart.get(i).id);
20230         }
20231         if (i < n) {
20232             Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
20233         }
20234     }
20235
20236     void finishUserBoot(UserState uss) {
20237         synchronized (this) {
20238             if (uss.mState == UserState.STATE_BOOTING
20239                     && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
20240                 uss.mState = UserState.STATE_RUNNING;
20241                 final int userId = uss.mHandle.getIdentifier();
20242                 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
20243                 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
20244                 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
20245                 broadcastIntentLocked(null, null, intent,
20246                         null, null, 0, null, null,
20247                         new String[] {android.Manifest.permission.RECEIVE_BOOT_COMPLETED},
20248                         AppOpsManager.OP_NONE, null, true, false, MY_PID, Process.SYSTEM_UID,
20249                         userId);
20250             }
20251         }
20252     }
20253
20254     void finishUserSwitch(UserState uss) {
20255         synchronized (this) {
20256             finishUserBoot(uss);
20257
20258             startProfilesLocked();
20259
20260             int num = mUserLru.size();
20261             int i = 0;
20262             while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
20263                 Integer oldUserId = mUserLru.get(i);
20264                 UserState oldUss = mStartedUsers.get(oldUserId);
20265                 if (oldUss == null) {
20266                     // Shouldn't happen, but be sane if it does.
20267                     mUserLru.remove(i);
20268                     num--;
20269                     continue;
20270                 }
20271                 if (oldUss.mState == UserState.STATE_STOPPING
20272                         || oldUss.mState == UserState.STATE_SHUTDOWN) {
20273                     // This user is already stopping, doesn't count.
20274                     num--;
20275                     i++;
20276                     continue;
20277                 }
20278                 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
20279                     // Owner and current can't be stopped, but count as running.
20280                     i++;
20281                     continue;
20282                 }
20283                 // This is a user to be stopped.
20284                 stopUserLocked(oldUserId, null);
20285                 num--;
20286                 i++;
20287             }
20288         }
20289     }
20290
20291     @Override
20292     public int stopUser(final int userId, final IStopUserCallback callback) {
20293         if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
20294                 != PackageManager.PERMISSION_GRANTED) {
20295             String msg = "Permission Denial: switchUser() from pid="
20296                     + Binder.getCallingPid()
20297                     + ", uid=" + Binder.getCallingUid()
20298                     + " requires " + INTERACT_ACROSS_USERS_FULL;
20299             Slog.w(TAG, msg);
20300             throw new SecurityException(msg);
20301         }
20302         if (userId < 0 || userId == UserHandle.USER_OWNER) {
20303             throw new IllegalArgumentException("Can't stop primary user " + userId);
20304         }
20305         enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
20306         synchronized (this) {
20307             return stopUserLocked(userId, callback);
20308         }
20309     }
20310
20311     private int stopUserLocked(final int userId, final IStopUserCallback callback) {
20312         if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
20313         if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) {
20314             return ActivityManager.USER_OP_IS_CURRENT;
20315         }
20316
20317         final UserState uss = mStartedUsers.get(userId);
20318         if (uss == null) {
20319             // User is not started, nothing to do...  but we do need to
20320             // callback if requested.
20321             if (callback != null) {
20322                 mHandler.post(new Runnable() {
20323                     @Override
20324                     public void run() {
20325                         try {
20326                             callback.userStopped(userId);
20327                         } catch (RemoteException e) {
20328                         }
20329                     }
20330                 });
20331             }
20332             return ActivityManager.USER_OP_SUCCESS;
20333         }
20334
20335         if (callback != null) {
20336             uss.mStopCallbacks.add(callback);
20337         }
20338
20339         if (uss.mState != UserState.STATE_STOPPING
20340                 && uss.mState != UserState.STATE_SHUTDOWN) {
20341             uss.mState = UserState.STATE_STOPPING;
20342             updateStartedUserArrayLocked();
20343
20344             long ident = Binder.clearCallingIdentity();
20345             try {
20346                 // We are going to broadcast ACTION_USER_STOPPING and then
20347                 // once that is done send a final ACTION_SHUTDOWN and then
20348                 // stop the user.
20349                 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
20350                 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
20351                 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
20352                 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
20353                 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
20354                 // This is the result receiver for the final shutdown broadcast.
20355                 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
20356                     @Override
20357                     public void performReceive(Intent intent, int resultCode, String data,
20358                             Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
20359                         finishUserStop(uss);
20360                     }
20361                 };
20362                 // This is the result receiver for the initial stopping broadcast.
20363                 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
20364                     @Override
20365                     public void performReceive(Intent intent, int resultCode, String data,
20366                             Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
20367                         // On to the next.
20368                         synchronized (ActivityManagerService.this) {
20369                             if (uss.mState != UserState.STATE_STOPPING) {
20370                                 // Whoops, we are being started back up.  Abort, abort!
20371                                 return;
20372                             }
20373                             uss.mState = UserState.STATE_SHUTDOWN;
20374                         }
20375                         mBatteryStatsService.noteEvent(
20376                                 BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
20377                                 Integer.toString(userId), userId);
20378                         mSystemServiceManager.stopUser(userId);
20379                         broadcastIntentLocked(null, null, shutdownIntent,
20380                                 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
20381                                 null, true, false, MY_PID, Process.SYSTEM_UID, userId);
20382                     }
20383                 };
20384                 // Kick things off.
20385                 broadcastIntentLocked(null, null, stoppingIntent,
20386                         null, stoppingReceiver, 0, null, null,
20387                         new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
20388                         null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
20389             } finally {
20390                 Binder.restoreCallingIdentity(ident);
20391             }
20392         }
20393
20394         return ActivityManager.USER_OP_SUCCESS;
20395     }
20396
20397     void finishUserStop(UserState uss) {
20398         final int userId = uss.mHandle.getIdentifier();
20399         boolean stopped;
20400         ArrayList<IStopUserCallback> callbacks;
20401         synchronized (this) {
20402             callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
20403             if (mStartedUsers.get(userId) != uss) {
20404                 stopped = false;
20405             } else if (uss.mState != UserState.STATE_SHUTDOWN) {
20406                 stopped = false;
20407             } else {
20408                 stopped = true;
20409                 // User can no longer run.
20410                 mStartedUsers.remove(userId);
20411                 mUserLru.remove(Integer.valueOf(userId));
20412                 updateStartedUserArrayLocked();
20413
20414                 // Clean up all state and processes associated with the user.
20415                 // Kill all the processes for the user.
20416                 forceStopUserLocked(userId, "finish user");
20417             }
20418
20419             // Explicitly remove the old information in mRecentTasks.
20420             mRecentTasks.removeTasksForUserLocked(userId);
20421         }
20422
20423         for (int i=0; i<callbacks.size(); i++) {
20424             try {
20425                 if (stopped) callbacks.get(i).userStopped(userId);
20426                 else callbacks.get(i).userStopAborted(userId);
20427             } catch (RemoteException e) {
20428             }
20429         }
20430
20431         if (stopped) {
20432             mSystemServiceManager.cleanupUser(userId);
20433             synchronized (this) {
20434                 mStackSupervisor.removeUserLocked(userId);
20435             }
20436         }
20437     }
20438
20439     @Override
20440     public UserInfo getCurrentUser() {
20441         if ((checkCallingPermission(INTERACT_ACROSS_USERS)
20442                 != PackageManager.PERMISSION_GRANTED) && (
20443                 checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
20444                 != PackageManager.PERMISSION_GRANTED)) {
20445             String msg = "Permission Denial: getCurrentUser() from pid="
20446                     + Binder.getCallingPid()
20447                     + ", uid=" + Binder.getCallingUid()
20448                     + " requires " + INTERACT_ACROSS_USERS;
20449             Slog.w(TAG, msg);
20450             throw new SecurityException(msg);
20451         }
20452         synchronized (this) {
20453             int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
20454             return getUserManagerLocked().getUserInfo(userId);
20455         }
20456     }
20457
20458     int getCurrentUserIdLocked() {
20459         return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
20460     }
20461
20462     @Override
20463     public boolean isUserRunning(int userId, boolean orStopped) {
20464         if (checkCallingPermission(INTERACT_ACROSS_USERS)
20465                 != PackageManager.PERMISSION_GRANTED) {
20466             String msg = "Permission Denial: isUserRunning() from pid="
20467                     + Binder.getCallingPid()
20468                     + ", uid=" + Binder.getCallingUid()
20469                     + " requires " + INTERACT_ACROSS_USERS;
20470             Slog.w(TAG, msg);
20471             throw new SecurityException(msg);
20472         }
20473         synchronized (this) {
20474             return isUserRunningLocked(userId, orStopped);
20475         }
20476     }
20477
20478     boolean isUserRunningLocked(int userId, boolean orStopped) {
20479         UserState state = mStartedUsers.get(userId);
20480         if (state == null) {
20481             return false;
20482         }
20483         if (orStopped) {
20484             return true;
20485         }
20486         return state.mState != UserState.STATE_STOPPING
20487                 && state.mState != UserState.STATE_SHUTDOWN;
20488     }
20489
20490     @Override
20491     public int[] getRunningUserIds() {
20492         if (checkCallingPermission(INTERACT_ACROSS_USERS)
20493                 != PackageManager.PERMISSION_GRANTED) {
20494             String msg = "Permission Denial: isUserRunning() from pid="
20495                     + Binder.getCallingPid()
20496                     + ", uid=" + Binder.getCallingUid()
20497                     + " requires " + INTERACT_ACROSS_USERS;
20498             Slog.w(TAG, msg);
20499             throw new SecurityException(msg);
20500         }
20501         synchronized (this) {
20502             return mStartedUserArray;
20503         }
20504     }
20505
20506     private void updateStartedUserArrayLocked() {
20507         int num = 0;
20508         for (int i=0; i<mStartedUsers.size();  i++) {
20509             UserState uss = mStartedUsers.valueAt(i);
20510             // This list does not include stopping users.
20511             if (uss.mState != UserState.STATE_STOPPING
20512                     && uss.mState != UserState.STATE_SHUTDOWN) {
20513                 num++;
20514             }
20515         }
20516         mStartedUserArray = new int[num];
20517         num = 0;
20518         for (int i=0; i<mStartedUsers.size();  i++) {
20519             UserState uss = mStartedUsers.valueAt(i);
20520             if (uss.mState != UserState.STATE_STOPPING
20521                     && uss.mState != UserState.STATE_SHUTDOWN) {
20522                 mStartedUserArray[num] = mStartedUsers.keyAt(i);
20523                 num++;
20524             }
20525         }
20526     }
20527
20528     @Override
20529     public void registerUserSwitchObserver(IUserSwitchObserver observer) {
20530         if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
20531                 != PackageManager.PERMISSION_GRANTED) {
20532             String msg = "Permission Denial: registerUserSwitchObserver() from pid="
20533                     + Binder.getCallingPid()
20534                     + ", uid=" + Binder.getCallingUid()
20535                     + " requires " + INTERACT_ACROSS_USERS_FULL;
20536             Slog.w(TAG, msg);
20537             throw new SecurityException(msg);
20538         }
20539
20540         mUserSwitchObservers.register(observer);
20541     }
20542
20543     @Override
20544     public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
20545         mUserSwitchObservers.unregister(observer);
20546     }
20547
20548     int[] getUsersLocked() {
20549         UserManagerService ums = getUserManagerLocked();
20550         return ums != null ? ums.getUserIds() : new int[] { 0 };
20551     }
20552
20553     UserManagerService getUserManagerLocked() {
20554         if (mUserManager == null) {
20555             IBinder b = ServiceManager.getService(Context.USER_SERVICE);
20556             mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
20557         }
20558         return mUserManager;
20559     }
20560
20561     private int applyUserId(int uid, int userId) {
20562         return UserHandle.getUid(userId, uid);
20563     }
20564
20565     ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
20566         if (info == null) return null;
20567         ApplicationInfo newInfo = new ApplicationInfo(info);
20568         newInfo.uid = applyUserId(info.uid, userId);
20569         newInfo.dataDir = Environment
20570                 .getDataUserPackageDirectory(info.volumeUuid, userId, info.packageName)
20571                 .getAbsolutePath();
20572         return newInfo;
20573     }
20574
20575     ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
20576         if (aInfo == null
20577                 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
20578             return aInfo;
20579         }
20580
20581         ActivityInfo info = new ActivityInfo(aInfo);
20582         info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
20583         return info;
20584     }
20585
20586     private final class LocalService extends ActivityManagerInternal {
20587         @Override
20588         public void onWakefulnessChanged(int wakefulness) {
20589             ActivityManagerService.this.onWakefulnessChanged(wakefulness);
20590         }
20591
20592         @Override
20593         public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
20594                 String processName, String abiOverride, int uid, Runnable crashHandler) {
20595             return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
20596                     processName, abiOverride, uid, crashHandler);
20597         }
20598
20599         @Override
20600         public SleepToken acquireSleepToken(String tag) {
20601             Preconditions.checkNotNull(tag);
20602
20603             synchronized (ActivityManagerService.this) {
20604                 SleepTokenImpl token = new SleepTokenImpl(tag);
20605                 mSleepTokens.add(token);
20606                 updateSleepIfNeededLocked();
20607                 return token;
20608             }
20609         }
20610
20611         @Override
20612         public ComponentName getHomeActivityForUser(int userId) {
20613             synchronized (ActivityManagerService.this) {
20614                 ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
20615                 return homeActivity == null ? null : homeActivity.realActivity;
20616             }
20617         }
20618     }
20619
20620     private final class SleepTokenImpl extends SleepToken {
20621         private final String mTag;
20622         private final long mAcquireTime;
20623
20624         public SleepTokenImpl(String tag) {
20625             mTag = tag;
20626             mAcquireTime = SystemClock.uptimeMillis();
20627         }
20628
20629         @Override
20630         public void release() {
20631             synchronized (ActivityManagerService.this) {
20632                 if (mSleepTokens.remove(this)) {
20633                     updateSleepIfNeededLocked();
20634                 }
20635             }
20636         }
20637
20638         @Override
20639         public String toString() {
20640             return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
20641         }
20642     }
20643
20644     /**
20645      * An implementation of IAppTask, that allows an app to manage its own tasks via
20646      * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
20647      * only the process that calls getAppTasks() can call the AppTask methods.
20648      */
20649     class AppTaskImpl extends IAppTask.Stub {
20650         private int mTaskId;
20651         private int mCallingUid;
20652
20653         public AppTaskImpl(int taskId, int callingUid) {
20654             mTaskId = taskId;
20655             mCallingUid = callingUid;
20656         }
20657
20658         private void checkCaller() {
20659             if (mCallingUid != Binder.getCallingUid()) {
20660                 throw new SecurityException("Caller " + mCallingUid
20661                         + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
20662             }
20663         }
20664
20665         @Override
20666         public void finishAndRemoveTask() {
20667             checkCaller();
20668
20669             synchronized (ActivityManagerService.this) {
20670                 long origId = Binder.clearCallingIdentity();
20671                 try {
20672                     if (!removeTaskByIdLocked(mTaskId, false)) {
20673                         throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20674                     }
20675                 } finally {
20676                     Binder.restoreCallingIdentity(origId);
20677                 }
20678             }
20679         }
20680
20681         @Override
20682         public ActivityManager.RecentTaskInfo getTaskInfo() {
20683             checkCaller();
20684
20685             synchronized (ActivityManagerService.this) {
20686                 long origId = Binder.clearCallingIdentity();
20687                 try {
20688                     TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
20689                     if (tr == null) {
20690                         throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20691                     }
20692                     return createRecentTaskInfoFromTaskRecord(tr);
20693                 } finally {
20694                     Binder.restoreCallingIdentity(origId);
20695                 }
20696             }
20697         }
20698
20699         @Override
20700         public void moveToFront() {
20701             checkCaller();
20702             // Will bring task to front if it already has a root activity.
20703             startActivityFromRecentsInner(mTaskId, null);
20704         }
20705
20706         @Override
20707         public int startActivity(IBinder whoThread, String callingPackage,
20708                 Intent intent, String resolvedType, Bundle options) {
20709             checkCaller();
20710
20711             int callingUser = UserHandle.getCallingUserId();
20712             TaskRecord tr;
20713             IApplicationThread appThread;
20714             synchronized (ActivityManagerService.this) {
20715                 tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
20716                 if (tr == null) {
20717                     throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20718                 }
20719                 appThread = ApplicationThreadNative.asInterface(whoThread);
20720                 if (appThread == null) {
20721                     throw new IllegalArgumentException("Bad app thread " + appThread);
20722                 }
20723             }
20724             return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent,
20725                     resolvedType, null, null, null, null, 0, 0, null, null,
20726                     null, options, false, callingUser, null, tr);
20727         }
20728
20729         @Override
20730         public void setExcludeFromRecents(boolean exclude) {
20731             checkCaller();
20732
20733             synchronized (ActivityManagerService.this) {
20734                 long origId = Binder.clearCallingIdentity();
20735                 try {
20736                     TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
20737                     if (tr == null) {
20738                         throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20739                     }
20740                     Intent intent = tr.getBaseIntent();
20741                     if (exclude) {
20742                         intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
20743                     } else {
20744                         intent.setFlags(intent.getFlags()
20745                                 & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
20746                     }
20747                 } finally {
20748                     Binder.restoreCallingIdentity(origId);
20749                 }
20750             }
20751         }
20752     }
20753 }